Skip to content

Commit a0a31fd

Browse files
zongboxpalmer-dabbelt
authored andcommitted
riscv: allocate a complete page size for each page table
Each page table should be created by allocating a complete page size for it. Otherwise, the content of the page table would be corrupted somewhere through memory allocation which allocates the memory at the middle of the page table for other use. Signed-off-by: Zong Li <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent e716704 commit a0a31fd

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

arch/riscv/mm/kasan_init.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,29 +46,34 @@ asmlinkage void __init kasan_early_init(void)
4646

4747
static void __init populate(void *start, void *end)
4848
{
49-
unsigned long i;
49+
unsigned long i, offset;
5050
unsigned long vaddr = (unsigned long)start & PAGE_MASK;
5151
unsigned long vend = PAGE_ALIGN((unsigned long)end);
5252
unsigned long n_pages = (vend - vaddr) / PAGE_SIZE;
53+
unsigned long n_ptes =
54+
((n_pages + PTRS_PER_PTE) & -PTRS_PER_PTE) / PTRS_PER_PTE;
5355
unsigned long n_pmds =
54-
(n_pages % PTRS_PER_PTE) ? n_pages / PTRS_PER_PTE + 1 :
55-
n_pages / PTRS_PER_PTE;
56+
((n_ptes + PTRS_PER_PMD) & -PTRS_PER_PMD) / PTRS_PER_PMD;
57+
58+
pte_t *pte =
59+
memblock_alloc(n_ptes * PTRS_PER_PTE * sizeof(pte_t), PAGE_SIZE);
60+
pmd_t *pmd =
61+
memblock_alloc(n_pmds * PTRS_PER_PMD * sizeof(pmd_t), PAGE_SIZE);
5662
pgd_t *pgd = pgd_offset_k(vaddr);
57-
pmd_t *pmd = memblock_alloc(n_pmds * sizeof(pmd_t), PAGE_SIZE);
58-
pte_t *pte = memblock_alloc(n_pages * sizeof(pte_t), PAGE_SIZE);
5963

6064
for (i = 0; i < n_pages; i++) {
6165
phys_addr_t phys = memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
62-
63-
set_pte(pte + i, pfn_pte(PHYS_PFN(phys), PAGE_KERNEL));
66+
set_pte(&pte[i], pfn_pte(PHYS_PFN(phys), PAGE_KERNEL));
6467
}
6568

66-
for (i = 0; i < n_pmds; ++pgd, i += PTRS_PER_PMD)
67-
set_pgd(pgd, pfn_pgd(PFN_DOWN(__pa(((uintptr_t)(pmd + i)))),
69+
for (i = 0, offset = 0; i < n_ptes; i++, offset += PTRS_PER_PTE)
70+
set_pmd(&pmd[i],
71+
pfn_pmd(PFN_DOWN(__pa(&pte[offset])),
6872
__pgprot(_PAGE_TABLE)));
6973

70-
for (i = 0; i < n_pages; ++pmd, i += PTRS_PER_PTE)
71-
set_pmd(pmd, pfn_pmd(PFN_DOWN(__pa((uintptr_t)(pte + i))),
74+
for (i = 0, offset = 0; i < n_pmds; i++, offset += PTRS_PER_PMD)
75+
set_pgd(&pgd[i],
76+
pfn_pgd(PFN_DOWN(__pa(&pmd[offset])),
7277
__pgprot(_PAGE_TABLE)));
7378

7479
flush_tlb_all();

0 commit comments

Comments
 (0)