We want to rework how pgd_page_vaddr() behaves for generic compile-time
folded page tables by disallowing its use and triggering a compile-time
error when it is used improperly, ensuring that the actual first-level
pXd_pgtable() function is used instead.

For this, change usage of pgd_page_vaddr() to pud_pgtable() for
the functions used when CONFIG_x86_PAE is enabled where PGTABLE_LEVELS=3
and replace direct check value of pgd_val() with pud_none().

There should be no functional change.

Signed-off-by: Yeoreum Yun <[email protected]>
---
 arch/x86/mm/pgtable.c | 41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index f32facdb30354..e4bf6a1d63618 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -207,14 +207,17 @@ static int preallocate_pmds(struct mm_struct *mm, pmd_t 
*pmds[], int count)
  */
 static void mop_up_one_pmd(struct mm_struct *mm, pgd_t *pgdp)
 {
-       pgd_t pgd = *pgdp;
+       pud_t *pudp, pud;
 
-       if (pgd_val(pgd) != 0) {
-               pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
+       pudp = pud_offset(p4d_offset(pgdp, 0), 0);
+       pud = *pudp;
 
-               pgd_clear(pgdp);
+       if (!pud_none(pud)) {
+               pmd_t *pmd = pud_pgtable(pud);
 
-               paravirt_release_pmd(pgd_val(pgd) >> PAGE_SHIFT);
+               pud_clear(pudp);
+
+               paravirt_release_pmd(pud_pfn(pud));
                pmd_free(mm, pmd);
                mm_dec_nr_pmds(mm);
        }
@@ -239,23 +242,24 @@ static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t 
*pgdp)
 #endif
 }
 
-static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t 
*pmds[])
+static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgdp, pmd_t 
*pmds[])
 {
-       p4d_t *p4d;
-       pud_t *pud;
+       pud_t *pudp, *pudp_s;
        int i;
 
-       p4d = p4d_offset(pgd, 0);
-       pud = pud_offset(p4d, 0);
+       pudp = pud_offset(p4d_offset(pgdp, 0), 0);
 
-       for (i = 0; i < PREALLOCATED_PMDS; i++, pud++) {
+       for (i = 0; i < PREALLOCATED_PMDS; i++, pudp++) {
                pmd_t *pmd = pmds[i];
 
-               if (i >= KERNEL_PGD_BOUNDARY)
-                       memcpy(pmd, (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
+               if (i >= KERNEL_PGD_BOUNDARY) {
+                       pudp_s = pud_offset(p4d_offset(&swapper_pg_dir[i], 0), 
0);
+
+                       memcpy(pmd, (pmd_t *)pud_pgtable(*pudp_s),
                               sizeof(pmd_t) * PTRS_PER_PMD);
+               }
 
-               pud_populate(mm, pud, pmd);
+               pud_populate(mm, pudp, pmd);
        }
 }
 
@@ -265,8 +269,8 @@ static void pgd_prepopulate_user_pmd(struct mm_struct *mm,
 {
        pgd_t *s_pgd = kernel_to_user_pgdp(swapper_pg_dir);
        pgd_t *u_pgd = kernel_to_user_pgdp(k_pgd);
-       p4d_t *u_p4d;
-       pud_t *u_pud;
+       p4d_t *s_p4d, *u_p4d;
+       pud_t *s_pud, *u_pud;
        int i;
 
        u_p4d = p4d_offset(u_pgd, 0);
@@ -278,7 +282,10 @@ static void pgd_prepopulate_user_pmd(struct mm_struct *mm,
        for (i = 0; i < PREALLOCATED_USER_PMDS; i++, u_pud++, s_pgd++) {
                pmd_t *pmd = pmds[i];
 
-               memcpy(pmd, (pmd_t *)pgd_page_vaddr(*s_pgd),
+               s_p4d = p4d_offset(s_pgd, 0);
+               s_pud = pud_offset(s_p4d, 0);
+
+               memcpy(pmd, (pmd_t *)pud_pgtable(*s_pud),
                       sizeof(pmd_t) * PTRS_PER_PMD);
 
                pud_populate(mm, u_pud, pmd);
-- 
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}


Reply via email to