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

Vincent Chen vincent.chen at sifive.com
Sun Apr 16 22:59:02 PDT 2023


On Fri, Apr 14, 2023 at 5:14 PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> On Fri, Apr 14, 2023 at 04:16:05PM +0800, Vincent Chen wrote:
> > The spare_init() calls memmap_populate() many times to create VA to PA
> > mapping for the VMEMMAP area, where all "strcut page" are located once
>
> struct
>
> > 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 hart to fail to perform page table work
>
> s/work/walk/ ?
>
> > because some data related to the address translation is invisible to the
> > hart. To solve this issue, the local_flush_tlb_kernel_range() is called
> > right after the spare_init() to execute a sfence.vma instruction for the
> > VMEMMAP area, ensuring that all data related to the address translation
> > is visible to the hart.
> >
> > Fixes: d95f1a542c3d ("RISC-V: Implement sparsemem")
> > Signed-off-by: Vincent Chen <vincent.chen at sifive.com>
> > Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > ---
> >  arch/riscv/include/asm/tlbflush.h | 7 +++++++
> >  arch/riscv/mm/init.c              | 5 +++++
> >  2 files changed, 12 insertions(+)
> >
> > diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
> > index a09196f8de68..f9d3712bd93b 100644
> > --- a/arch/riscv/include/asm/tlbflush.h
> > +++ b/arch/riscv/include/asm/tlbflush.h
> > @@ -61,4 +61,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 478d6763a01a..5bd96f6c8f19 100644
> > --- a/arch/riscv/mm/init.c
> > +++ b/arch/riscv/mm/init.c
> > @@ -1231,6 +1231,10 @@ void __init misc_mem_init(void)
> >       early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT);
> >       arch_numa_init();
> >       sparse_init();
> > +#ifdef CONFIG_SPARSEMEM_VMEMMAP
> > +     /* The entire VMEMMAP region has been propulated. Flush TLB for this region */
>
> populated
>
> > +     local_flush_tlb_kernel_range(VMEMMAP_START, VMEMMAP_END);
> > +#endif
> >       zone_sizes_init();
> >       reserve_crashkernel();
> >       memblock_dump_all();
> > @@ -1240,6 +1244,7 @@ void __init misc_mem_init(void)
> >  int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
> >                              struct vmem_altmap *altmap)
> >  {
> > +     /* Defer the required TLB flush until the entire VMEMMAP region has been populated */
> >       return vmemmap_populate_basepages(start, end, node, NULL);
> >  }
> >  #endif
> > --
> > 2.25.1
> >
>
> Besides the typos,

Thank you for finding these typos. It's really embarrassing. I will
fix these issues in the patch for v3.

Thanks,
Vincent
>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>
> Thanks,
> drew



More information about the linux-riscv mailing list