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}
