[PATCH] riscv: mm: execute local TLB flush after populating vmemmap

Vincent Chen vincent.chen at sifive.com
Sun Mar 19 23:53:24 PDT 2023


The vmemmap_populate() creates VA to PA mapping for the VMEMMAP area, where
all "strcut page" are located once CONFIG_SPARSEMEM_VMEMMAP is defined.
These "struct page" are later initialized in the zone_sizes_init()
function. However, during this process, no sfence.vma instruction is
executed for this VMEMMAP area. This omission may cause the core to fail to
perform page table work because some data related to the address
translation is invisible to the core. To solve this issue, here let
zone_sizes_init() call local_flush_tlb_kernel_range() to execute a
sfence.vma instruction for the VMEMMAP area, ensuring that all data related
to the address translation is visible to the core.

Signed-off-by: Vincent Chen <vincent.chen at sifive.com>
---
 arch/riscv/include/asm/tlbflush.h | 7 +++++++
 arch/riscv/mm/init.c              | 3 +++
 2 files changed, 10 insertions(+)

diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index 801019381dea..b7696974e3c6 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -59,4 +59,11 @@ static inline void flush_tlb_kernel_range(unsigned long start,
 	flush_tlb_all();
 }
 
+/* Flush a range of kernel pages without broadcasting */
+static inline void local_flush_tlb_kernel_range(unsigned long start,
+						unsigned long end)
+{
+	local_flush_tlb_all();
+}
+
 #endif /* _ASM_RISCV_TLBFLUSH_H */
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 2c4a64e97aec..62eea656e341 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -72,6 +72,9 @@ static void __init zone_sizes_init(void)
 #endif
 	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+	local_flush_tlb_kernel_range(VMEMMAP_START, VMEMMAP_END);
+#endif
 	free_area_init(max_zone_pfns);
 }
 
-- 
2.25.1




More information about the linux-riscv mailing list