Skip to content

Commit 855ad0f

Browse files
Merge patch series "riscv: fix debug_pagealloc"
Nam Cao <[email protected]> says: The debug_pagealloc feature is not functional on RISCV. With this feature enabled (CONFIG_DEBUG_PAGEALLOC=y and debug_pagealloc=on), kernel crashes early during boot. QEMU command that can reproduce this problem: qemu-system-riscv64 -machine virt \ -kernel Image \ -append "console=ttyS0 root=/dev/vda debug_pagealloc=on" \ -nographic \ -drive "file=root.img,format=raw,id=hd0" \ -device virtio-blk-device,drive=hd0 \ -m 4G \ This series makes debug_pagealloc functional. * b4-shazam-merge: riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context riscv: force PAGE_SIZE linear mapping if debug_pagealloc is enabled Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
2 parents a2a4d4a + fb1cf08 commit 855ad0f

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

arch/riscv/mm/init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,9 @@ void __init create_pgd_mapping(pgd_t *pgdp,
683683
static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va,
684684
phys_addr_t size)
685685
{
686+
if (debug_pagealloc_enabled())
687+
return PAGE_SIZE;
688+
686689
if (pgtable_l5_enabled &&
687690
!(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE)
688691
return P4D_SIZE;

arch/riscv/mm/pageattr.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,17 +387,33 @@ int set_direct_map_default_noflush(struct page *page)
387387
}
388388

389389
#ifdef CONFIG_DEBUG_PAGEALLOC
390+
static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
391+
{
392+
int enable = *(int *)data;
393+
394+
unsigned long val = pte_val(ptep_get(pte));
395+
396+
if (enable)
397+
val |= _PAGE_PRESENT;
398+
else
399+
val &= ~_PAGE_PRESENT;
400+
401+
set_pte(pte, __pte(val));
402+
403+
return 0;
404+
}
405+
390406
void __kernel_map_pages(struct page *page, int numpages, int enable)
391407
{
392408
if (!debug_pagealloc_enabled())
393409
return;
394410

395-
if (enable)
396-
__set_memory((unsigned long)page_address(page), numpages,
397-
__pgprot(_PAGE_PRESENT), __pgprot(0));
398-
else
399-
__set_memory((unsigned long)page_address(page), numpages,
400-
__pgprot(0), __pgprot(_PAGE_PRESENT));
411+
unsigned long start = (unsigned long)page_address(page);
412+
unsigned long size = PAGE_SIZE * numpages;
413+
414+
apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable);
415+
416+
flush_tlb_kernel_range(start, start + size);
401417
}
402418
#endif
403419

0 commit comments

Comments
 (0)