parisc: fix map_pages() to actually populate upper directory
PATCH 1/1 parisc: fix map_pages() to actually populate upper directory
From: Mike Rapoport <[email protected]>
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.
--- arch/parisc/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/mm/init.c +1 -1
@@ -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 pg_dir++;
Signature · 1 line
2.24.0
Helge Deller
maintainerQuoted 14 lines
The commit
d96885e277b5("parisc: use pgtable-nopXd instead of 4level-fixup") converted PA-RISC to use folded page tables, but it missed the conversion ofpgd_populate()topud_populate()inmaps_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 dummypgd_populate()fixes the issue.
...arch/parisc/mm/init.c +0
-0
arch/parisc/mm/init.c static void __init map_pages(unsigned long start_vaddr, · line 405
Quoted 6 lines
arch/parisc/mm/init.c +1
-1@@ -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
arch/parisc/mm/init.c +5 -1
@@ -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++;
Hi,
Quoted 39 lines · Helge Deller
Quoted 14 lines
The commit
d96885e277b5("parisc: use pgtable-nopXd instead of 4level-fixup") converted PA-RISC to use folded page tables, but it missed the conversion ofpgd_populate()topud_populate()inmaps_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 dummypgd_populate()fixes the issue.
...arch/parisc/mm/init.c +0
-0arch/parisc/mm/init.c static void __init map_pages(unsigned long start_vaddr, · line 405
Quoted 6 lines
arch/parisc/mm/init.c +1
-1@@ -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
arch/parisc/mm/init.c +2
-0@@ -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);/*
arch/parisc/mm/init.c static void __init map_pages(unsigned long start_vaddr, · line 410
Quoted 9 lines
arch/parisc/mm/init.c +3
-1@@ -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:
arch/parisc/mm/init.c +11 -34
@@ -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;
Signature · 2 lines
Sincerely yours, Mike.
Helge Deller
maintainerQuoted 45 lines · Mike Rapoport
Hi,
Quoted 42 lines · Helge Deller
Quoted 14 lines
The commit
d96885e277b5("parisc: use pgtable-nopXd instead of 4level-fixup") converted PA-RISC to use folded page tables, but it missed the conversion ofpgd_populate()topud_populate()inmaps_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 dummypgd_populate()fixes the issue.
...arch/parisc/mm/init.c +0
-0arch/parisc/mm/init.c static void __init map_pages(unsigned long start_vaddr, · line 405
Quoted 6 lines
arch/parisc/mm/init.c +1
-1@@ -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
arch/parisc/mm/init.c +2
-0@@ -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); }
Quoted 9 lines
arch/parisc/mm/init.c static void __init map_pages(unsigned long start_vaddr, · line 410
Quoted 6 lines
arch/parisc/mm/init.c +3
-1-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:
Ok, then let's use the small fix for v5.5, and the bigger one for v5.6. I'll push the small fixup to Linux through the parisc tree shortly.
Would you mind resending the full cleanup patch for v5.6 later again ?
Thanks!!
Helge
Quoted 86 lines
arch/parisc/mm/init.c +11
-34@@ -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;