Merge patch series "riscv: fix debug_pagealloc"
Nam Cao <namcao@linutronix.de> 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/cover.1715750938.git.namcao@linutronix.de Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
commit
855ad0f7a1
@ -683,6 +683,9 @@ void __init create_pgd_mapping(pgd_t *pgdp,
|
|||||||
static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va,
|
static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va,
|
||||||
phys_addr_t size)
|
phys_addr_t size)
|
||||||
{
|
{
|
||||||
|
if (debug_pagealloc_enabled())
|
||||||
|
return PAGE_SIZE;
|
||||||
|
|
||||||
if (pgtable_l5_enabled &&
|
if (pgtable_l5_enabled &&
|
||||||
!(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE)
|
!(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE)
|
||||||
return P4D_SIZE;
|
return P4D_SIZE;
|
||||||
|
@ -387,17 +387,33 @@ int set_direct_map_default_noflush(struct page *page)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||||
|
static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
|
||||||
|
{
|
||||||
|
int enable = *(int *)data;
|
||||||
|
|
||||||
|
unsigned long val = pte_val(ptep_get(pte));
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
val |= _PAGE_PRESENT;
|
||||||
|
else
|
||||||
|
val &= ~_PAGE_PRESENT;
|
||||||
|
|
||||||
|
set_pte(pte, __pte(val));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void __kernel_map_pages(struct page *page, int numpages, int enable)
|
void __kernel_map_pages(struct page *page, int numpages, int enable)
|
||||||
{
|
{
|
||||||
if (!debug_pagealloc_enabled())
|
if (!debug_pagealloc_enabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (enable)
|
unsigned long start = (unsigned long)page_address(page);
|
||||||
__set_memory((unsigned long)page_address(page), numpages,
|
unsigned long size = PAGE_SIZE * numpages;
|
||||||
__pgprot(_PAGE_PRESENT), __pgprot(0));
|
|
||||||
else
|
apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable);
|
||||||
__set_memory((unsigned long)page_address(page), numpages,
|
|
||||||
__pgprot(0), __pgprot(_PAGE_PRESENT));
|
flush_tlb_kernel_range(start, start + size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user