[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20260112075643.124570-1-guoyaxing@bosc.ac.cn>
Date: Mon, 12 Jan 2026 15:56:43 +0800
From: Yaxing Guo <guoyaxing@...c.ac.cn>
To: pjw@...nel.org,
palmer@...belt.com,
aou@...s.berkeley.edu,
alex@...ti.fr,
ryabinin.a.a@...il.com,
glider@...gle.com,
andreyknvl@...il.com,
dvyukov@...gle.com,
vincenzo.frascino@....com
Cc: guoyaxing@...c.ac.cn,
majiuyue@...c.ac.cn,
linux-riscv@...ts.infradead.org,
linux-kernel@...r.kernel.org,
Zhizun Wang <anzoso@...look.com>
Subject: [PATCH v1] riscv/kasan: include KASAN shadow range in flush_cache_vmap()
On RISC-V, when vmalloc() allocates memory for the KASAN shadow region,
the page table entries are set up without ensuring the store operations
are globally visible before subsequent accesses. The flush logic
in handle_exception relies on the 'new_vmalloc' bit to trigger a fence,
but this bit is only set for vmalloc/module addresses — not for KASAN
shadow addresses.
As a result, accesses to the newly mapped KASAN shadow memory can trigger
spurious page faults due to stale TLB or instruction cache entries.
Fix this by extending flush_cache_vmap() to also cover the KASAN shadow
address range, ensuring proper cache maintenance and memory ordering
for KASAN shadow mappings just like regular vmalloc areas.
Reported-by: Zhizun Wang <anzoso@...look.com>
Reported-by: Jiuyue Ma <majiuyue@...c.ac.cn>
Signed-off-by: Yaxing Guo <guoyaxing@...c.ac.cn>
---
arch/riscv/include/asm/cacheflush.h | 4 +++-
arch/riscv/include/asm/kasan.h | 6 +++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index 0092513c3376..b27480d5a205 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -7,6 +7,7 @@
#define _ASM_RISCV_CACHEFLUSH_H
#include <linux/mm.h>
+#include <asm/kasan.h>
static inline void local_flush_icache_all(void)
{
@@ -46,7 +47,8 @@ extern char _end[];
#define flush_cache_vmap flush_cache_vmap
static inline void flush_cache_vmap(unsigned long start, unsigned long end)
{
- if (is_vmalloc_or_module_addr((void *)start)) {
+ if (is_vmalloc_or_module_addr((void *)start) ||
+ is_kasan_addr(start)) {
int i;
/*
diff --git a/arch/riscv/include/asm/kasan.h b/arch/riscv/include/asm/kasan.h
index 60af6691f903..224ba86fbd15 100644
--- a/arch/riscv/include/asm/kasan.h
+++ b/arch/riscv/include/asm/kasan.h
@@ -36,10 +36,14 @@
#ifdef CONFIG_KASAN
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define is_kasan_addr(addr) (addr >= KASAN_SHADOW_START && addr < KASAN_SHADOW_END)
+
void kasan_init(void);
asmlinkage void kasan_early_init(void);
void kasan_swapper_init(void);
-
+#else
+#define is_kasan_addr(addr) (0)
#endif
+
#endif
#endif /* __ASM_KASAN_H */
--
2.34.1
Powered by blists - more mailing lists