Skip to content

Commit 7a92fc8

Browse files
Alexandre Ghitidennisszhou
authored andcommitted
mm: Introduce flush_cache_vmap_early()
The pcpu setup when using the page allocator sets up a new vmalloc mapping very early in the boot process, so early that it cannot use the flush_cache_vmap() function which may depend on structures not yet initialized (for example in riscv, we currently send an IPI to flush other cpus TLB). But on some architectures, we must call flush_cache_vmap(): for example, in riscv, some uarchs can cache invalid TLB entries so we need to flush the new established mapping to avoid taking an exception. So fix this by introducing a new function flush_cache_vmap_early() which is called right after setting the new page table entry and before accessing this new mapping. This new function implements a local flush tlb on riscv and is no-op for other architectures (same as today). Signed-off-by: Alexandre Ghiti <[email protected]> Acked-by: Geert Uytterhoeven <[email protected]> Signed-off-by: Dennis Zhou <[email protected]>
1 parent 33cc938 commit 7a92fc8

File tree

17 files changed

+32
-10
lines changed

17 files changed

+32
-10
lines changed

arch/arc/include/asm/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void dma_cache_wback(phys_addr_t start, unsigned long sz);
4040

4141
/* TBD: optimize this */
4242
#define flush_cache_vmap(start, end) flush_cache_all()
43+
#define flush_cache_vmap_early(start, end) do { } while (0)
4344
#define flush_cache_vunmap(start, end) flush_cache_all()
4445

4546
#define flush_cache_dup_mm(mm) /* called on fork (VIVT only) */

arch/arm/include/asm/cacheflush.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ static inline void flush_cache_vmap(unsigned long start, unsigned long end)
340340
dsb(ishst);
341341
}
342342

343+
#define flush_cache_vmap_early(start, end) do { } while (0)
344+
343345
static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
344346
{
345347
if (!cache_is_vipt_nonaliasing())

arch/csky/abiv1/inc/abi/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
4343
*/
4444
extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
4545
#define flush_cache_vmap(start, end) cache_wbinv_all()
46+
#define flush_cache_vmap_early(start, end) do { } while (0)
4647
#define flush_cache_vunmap(start, end) cache_wbinv_all()
4748

4849
#define flush_icache_range(start, end) cache_wbinv_range(start, end)

arch/csky/abiv2/inc/abi/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ void flush_icache_mm_range(struct mm_struct *mm,
4141
void flush_icache_deferred(struct mm_struct *mm);
4242

4343
#define flush_cache_vmap(start, end) do { } while (0)
44+
#define flush_cache_vmap_early(start, end) do { } while (0)
4445
#define flush_cache_vunmap(start, end) do { } while (0)
4546

4647
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \

arch/m68k/include/asm/cacheflush_mm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ extern void cache_push_v(unsigned long vaddr, int len);
191191
#define flush_cache_all() __flush_cache_all()
192192

193193
#define flush_cache_vmap(start, end) flush_cache_all()
194+
#define flush_cache_vmap_early(start, end) do { } while (0)
194195
#define flush_cache_vunmap(start, end) flush_cache_all()
195196

196197
static inline void flush_cache_mm(struct mm_struct *mm)

arch/mips/include/asm/cacheflush.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ static inline void flush_cache_vmap(unsigned long start, unsigned long end)
9797
__flush_cache_vmap();
9898
}
9999

100+
#define flush_cache_vmap_early(start, end) do { } while (0)
101+
100102
extern void (*__flush_cache_vunmap)(void);
101103

102104
static inline void flush_cache_vunmap(unsigned long start, unsigned long end)

arch/nios2/include/asm/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ void flush_icache_pages(struct vm_area_struct *vma, struct page *page,
3838
#define flush_icache_pages flush_icache_pages
3939

4040
#define flush_cache_vmap(start, end) flush_dcache_range(start, end)
41+
#define flush_cache_vmap_early(start, end) do { } while (0)
4142
#define flush_cache_vunmap(start, end) flush_dcache_range(start, end)
4243

4344
extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page,

arch/parisc/include/asm/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ void flush_kernel_vmap_range(void *vaddr, int size);
4141
void invalidate_kernel_vmap_range(void *vaddr, int size);
4242

4343
#define flush_cache_vmap(start, end) flush_cache_all()
44+
#define flush_cache_vmap_early(start, end) do { } while (0)
4445
#define flush_cache_vunmap(start, end) flush_cache_all()
4546

4647
void flush_dcache_folio(struct folio *folio);

arch/riscv/include/asm/cacheflush.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ static inline void flush_dcache_page(struct page *page)
3737
flush_icache_mm(vma->vm_mm, 0)
3838

3939
#ifdef CONFIG_64BIT
40-
#define flush_cache_vmap(start, end) flush_tlb_kernel_range(start, end)
40+
#define flush_cache_vmap(start, end) flush_tlb_kernel_range(start, end)
41+
#define flush_cache_vmap_early(start, end) local_flush_tlb_kernel_range(start, end)
4142
#endif
4243

4344
#ifndef CONFIG_SMP

arch/riscv/include/asm/tlbflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
4141
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
4242
unsigned long end);
4343
void flush_tlb_kernel_range(unsigned long start, unsigned long end);
44+
void local_flush_tlb_kernel_range(unsigned long start, unsigned long end);
4445
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
4546
#define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
4647
void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,

0 commit comments

Comments
 (0)