[PATCH] riscv: mm: execute local TLB flush after populating vmemmap
Alexandre Ghiti
alex at ghiti.fr
Tue Mar 21 09:11:50 PDT 2023
Hi Vincent,
On 3/20/23 07:53, Vincent Chen wrote:
> 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);
> }
>
Just one nit: I would have added the flush to the vmemmap_populate
function instead, so that we don't flush uselessly when !SPARSE_VMEMMAP
and we know exactly why we flush.
Otherwise, you can add:
Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Thanks,
Alex
More information about the linux-riscv
mailing list