section_activate() creates new mappings in the vmemmap range without flushing TLB, which may cause faults on some RISC-V implementations that cache non-present PTEs and crashes. This seems to be most easily reproduced with DEBUG_VM=y and PAGE_POISONING=y, which causes these newly mapped struct pages to be poisoned i.e. written to immediately after mapping. Implement the newly added hook vmemmap_populate_finalize() on RISC-V, to arrange for the existing exception handler code to deal with these faults if they happen. Signed-off-by: Vivian Wang --- I put the declaration here since it's the file where vmemmap and the vmemmap area addresses are defined. Depends on my kfence patches for mark_new_valid_map() (see cover). --- arch/riscv/include/asm/pgtable.h | 4 ++++ arch/riscv/mm/init.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index a1a7c6520a09..aa0f50e3d534 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -1243,6 +1243,10 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte) #define TASK_SIZE FIXADDR_START #endif +/* Needed on SPARSEMEM_VMEMMAP */ +#define vmemmap_populate_finalize vmemmap_populate_finalize +void __meminit vmemmap_populate_finalize(void); + #else /* CONFIG_MMU */ #define PAGE_SHARED __pgprot(0) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 706f43523935..cf9ae4099f82 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -1360,6 +1360,12 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, */ return vmemmap_populate_hugepages(start, end, node, altmap); } + +void __meminit vmemmap_populate_finalize(void) +{ + /* Avoid faults on cached non-present TLB entries. */ + mark_new_valid_map(); +} #endif #if defined(CONFIG_MMU) && defined(CONFIG_64BIT) -- 2.54.0