aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pgtable.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm/pgtable.c')
-rw-r--r--arch/x86/mm/pgtable.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 004abf9ebf12..34cda7e0551b 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -702,4 +702,52 @@ int pmd_clear_huge(pmd_t *pmd)
702 702
703 return 0; 703 return 0;
704} 704}
705
706/**
707 * pud_free_pmd_page - Clear pud entry and free pmd page.
708 * @pud: Pointer to a PUD.
709 *
710 * Context: The pud range has been unmaped and TLB purged.
711 * Return: 1 if clearing the entry succeeded. 0 otherwise.
712 */
713int pud_free_pmd_page(pud_t *pud)
714{
715 pmd_t *pmd;
716 int i;
717
718 if (pud_none(*pud))
719 return 1;
720
721 pmd = (pmd_t *)pud_page_vaddr(*pud);
722
723 for (i = 0; i < PTRS_PER_PMD; i++)
724 if (!pmd_free_pte_page(&pmd[i]))
725 return 0;
726
727 pud_clear(pud);
728 free_page((unsigned long)pmd);
729
730 return 1;
731}
732
733/**
734 * pmd_free_pte_page - Clear pmd entry and free pte page.
735 * @pmd: Pointer to a PMD.
736 *
737 * Context: The pmd range has been unmaped and TLB purged.
738 * Return: 1 if clearing the entry succeeded. 0 otherwise.
739 */
740int pmd_free_pte_page(pmd_t *pmd)
741{
742 pte_t *pte;
743
744 if (pmd_none(*pmd))
745 return 1;
746
747 pte = (pte_t *)pmd_page_vaddr(*pmd);
748 pmd_clear(pmd);
749 free_page((unsigned long)pte);
750
751 return 1;
752}
705#endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ 753#endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */