Hi, On Thu, Jan 09, 2020 at 07:50:55AM +0100, Helge Deller wrote: > > The commit d96885e277b5 ("parisc: use pgtable-nopXd instead of > > 4level-fixup") converted PA-RISC to use folded page tables, but it missed > > the conversion of pgd_populate() to pud_populate() in maps_pages() > > function. This caused the upper page table directory to remain empty and > > the system would crash as a result. > > > > Using pud_populate() that actually populates the page table instead of > > dummy pgd_populate() fixes the issue. > > ... > > diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c > > index ddca8287d43b..354cf060b67f 100644 > > --- a/arch/parisc/mm/init.c > > +++ b/arch/parisc/mm/init.c > > @@ -401,7 +401,7 @@ static void __init map_pages(unsigned long start_vaddr, > > pmd = (pmd_t *) __pa(pmd); > > } > > > > - pgd_populate(NULL, pg_dir, __va(pmd)); > > + pud_populate(NULL, (pud_t *)pg_dir, __va(pmd)); > > #endif > > Wouldn't the untested patch below be more clean? > > Helge > > diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c > index ddca8287d43b..73de58f31f5f 100644 > --- a/arch/parisc/mm/init.c > +++ b/arch/parisc/mm/init.c > @@ -387,6 +387,8 @@ static void __init map_pages(unsigned long start_vaddr, > #if PTRS_PER_PMD == 1 > pmd = (pmd_t *)__pa(pg_dir); > #else > + p4d_t *p4d; > + pud_t *pud; > pmd = (pmd_t *)pgd_address(*pg_dir); > > /* > @@ -401,7 +403,9 @@ static void __init map_pages(unsigned long start_vaddr, > pmd = (pmd_t *) __pa(pmd); > } > > - pgd_populate(NULL, pg_dir, __va(pmd)); > + p4d = p4d_offset(pg_dir, vaddr); > + pud = pud_offset(p4d, vaddr); > + pud_populate(NULL, pud, __va(pmd)); > #endif > pg_dir++; I've tried to keep the changes to minimum :) Otherwise I'd go with something even more surgical: diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 354cf060b67f..94baa4382c29 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -351,7 +351,6 @@ static void __init map_pages(unsigned long start_vaddr, unsigned long start_paddr, unsigned long size, pgprot_t pgprot, int force) { - pgd_t *pg_dir; pmd_t *pmd; pte_t *pg_table; unsigned long end_paddr; @@ -372,8 +371,6 @@ static void __init map_pages(unsigned long start_vaddr, end_paddr = start_paddr + size; - pg_dir = pgd_offset_k(start_vaddr); - #if PTRS_PER_PMD == 1 start_pmd = 0; #else @@ -384,50 +381,30 @@ static void __init map_pages(unsigned long start_vaddr, address = start_paddr; vaddr = start_vaddr; while (address < end_paddr) { -#if PTRS_PER_PMD == 1 - pmd = (pmd_t *)__pa(pg_dir); -#else - pmd = (pmd_t *)pgd_address(*pg_dir); + pgd_t *pgd = pgd_offset_k(vaddr); + p4d_t *p4d = p4d_offset(pgd, vaddr); + pud_t *pud = pud_offset(p4d, vaddr); - /* - * pmd is physical at this point - */ - - if (!pmd) { +#if CONFIG_PGTABLE_LEVELS == 3 + if (pud_none(*pud)) { pmd = memblock_alloc(PAGE_SIZE << PMD_ORDER, PAGE_SIZE << PMD_ORDER); if (!pmd) panic("pmd allocation failed.\n"); - pmd = (pmd_t *) __pa(pmd); + pud_populate(NULL, pud, pmd); } - - pud_populate(NULL, (pud_t *)pg_dir, __va(pmd)); #endif - pg_dir++; - /* now change pmd to kernel virtual addresses */ - - pmd = (pmd_t *)__va(pmd) + start_pmd; + pmd = pmd_offset(pud, vaddr); for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++, pmd++) { - - /* - * pg_table is physical at this point - */ - - pg_table = (pte_t *)pmd_address(*pmd); - if (!pg_table) { - pg_table = memblock_alloc(PAGE_SIZE, - PAGE_SIZE); + if (pmd_none(*pmd)) { + pg_table = memblock_alloc(PAGE_SIZE, PAGE_SIZE); if (!pg_table) panic("page table allocation failed\n"); - pg_table = (pte_t *) __pa(pg_table); + pmd_populate_kernel(NULL, pmd, pg_table); } - pmd_populate_kernel(NULL, pmd, __va(pg_table)); - - /* now change pg_table to kernel virtual addresses */ - - pg_table = (pte_t *) __va(pg_table) + start_pte; + pg_table = pte_offset_kernel(pmd, vaddr); for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) { pte_t pte; pgprot_t prot; -- Sincerely yours, Mike.