* [PATCH] riscv: mm: Fix concurrency in mark_new_valid_map()
@ 2026-06-29 9:25 Vivian Wang
2026-07-10 0:59 ` Paul Walmsley
0 siblings, 1 reply; 2+ messages in thread
From: Vivian Wang @ 2026-06-29 9:25 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Alexandre Ghiti
Cc: linux-riscv, linux-kernel, Yaxing Guo, David Hildenbrand (Arm),
Vivian Wang
Turns out, the concurrency concerns [1] were justified - BOSC reported a
spurious fault in KFENCE that still triggers despite previous fixes,
which KFENCE reports as a false-positive.
Fix the concurrency problems in mark_new_valid_map():
- Add smp_wmb() before filling the bitmap, to make sure page table
writes are "received".
- Use WRITE_ONCE() to fill the bitmap.
This fixes the KFENCE false positives in internal testing.
Also update comments in the assembly exception handler code to match.
Fixes: 26c171fc4853 ("riscv: mm: Use the bitmap API for new_valid_map_cpus")
Reported-by: Yaxing Guo <guoyaxing@bosc.ac.cn>
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Link: https://lore.kernel.org/linux-riscv/da19ffcf-8042-4f96-9c2d-649468dc6a0a@kernel.org/ # [1]
Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
---
arch/riscv/include/asm/cacheflush.h | 15 ++++++++++++++-
arch/riscv/kernel/entry.S | 11 ++++-------
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index 8cfe59483a8f..1f191cf801a2 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -6,7 +6,9 @@
#ifndef _ASM_RISCV_CACHEFLUSH_H
#define _ASM_RISCV_CACHEFLUSH_H
+#include <linux/array_size.h>
#include <linux/mm.h>
+#include <asm/barrier.h>
static inline void local_flush_icache_all(void)
{
@@ -46,12 +48,23 @@ extern DECLARE_BITMAP(new_valid_map_cpus, NR_CPUS);
extern char _end[];
static inline void mark_new_valid_map(void)
{
+ /*
+ * Orders any previous page table writes before setting bits in
+ * new_valid_map_cpus. Pairs with the sfence.vma in
+ * new_valid_map_cpus_check.
+ */
+ smp_wmb();
+
/*
* We don't care if concurrently a cpu resets this value since
* the only place this can happen is in handle_exception() where
* an sfence.vma is emitted.
+ *
+ * Not memset() or bitmap_fill() to avoid any possible compiler
+ * shenanigans.
*/
- bitmap_fill(new_valid_map_cpus, NR_CPUS);
+ for (size_t i = 0; i < ARRAY_SIZE(new_valid_map_cpus); i++)
+ WRITE_ONCE(new_valid_map_cpus[i], -1UL);
}
#define flush_cache_vmap flush_cache_vmap
static inline void flush_cache_vmap(unsigned long start, unsigned long end)
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index c6988983cdf7..092f408edb7d 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -76,6 +76,8 @@
amoxor.d a0, a1, (a0)
/*
+ * Pairs with the smp_wmb() in mark_new_valid_map()
+ *
* A sfence.vma is required here. Even if we had Svvptc, there's no
* guarantee that after returning we wouldn't just fault again.
*/
@@ -141,13 +143,8 @@ SYM_CODE_START(handle_exception)
/*
* The RISC-V kernel does not flush TLBs on all CPUS after each new
* vmalloc mapping or kfence_unprotect(), which may result in
- * exceptions:
- *
- * - if the uarch caches invalid entries, the new mapping would not be
- * observed by the page table walker and an invalidation is needed.
- * - if the uarch does not cache invalid entries, a reordered access
- * could "miss" the new mapping and traps: in that case, we only need
- * to retry the access, no sfence.vma is required.
+ * exceptions. In that case, we need to sfence.vma to "receive" the new
+ * mappings and retry, whether or not we have Svvptc.
*/
new_valid_map_cpus_check
#endif
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260629-riscv-mm-new-valid-map-ordering-007fa3841332
Best regards,
--
Vivian Wang <wangruikang@iscas.ac.cn>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] riscv: mm: Fix concurrency in mark_new_valid_map()
2026-06-29 9:25 [PATCH] riscv: mm: Fix concurrency in mark_new_valid_map() Vivian Wang
@ 2026-07-10 0:59 ` Paul Walmsley
0 siblings, 0 replies; 2+ messages in thread
From: Paul Walmsley @ 2026-07-10 0:59 UTC (permalink / raw)
To: Vivian Wang
Cc: Paul Walmsley, Palmer Dabbelt, Alexandre Ghiti, linux-riscv,
linux-kernel, Yaxing Guo, David Hildenbrand (Arm)
Hi Vivian,
On Mon, 29 Jun 2026, Vivian Wang wrote:
> Turns out, the concurrency concerns [1] were justified - BOSC reported a
> spurious fault in KFENCE that still triggers despite previous fixes,
> which KFENCE reports as a false-positive.
>
> Fix the concurrency problems in mark_new_valid_map():
>
> - Add smp_wmb() before filling the bitmap, to make sure page table
> writes are "received".
Probably this expression should be clarified. I guess the intent here is
to ensure that the page table write is visible by other cores either
before or simultaneously with the bitmap fill? And the purpose of that is
to avoid a situation where another core could execute an sfence.vma before
the PTE write is observable by the other core? If so, we should probably
write something like this out in the commit message.
I wonder if there's still a window where spurious faults could be observed
by kfence. If another core "B" faults (due to its local TLB caching an
invalid PTE) after the PTE write is observable by B, but before the bitmap
write is observable by B, core B won't sfence.vma. If this possibility
still exists, we should probably document it. It might be possible to
narrow that window further with a smp_mb() after the bitmap fill, but
unclear that it's worth trying unless more spurious faults are seen.
...
Also, now that we're adding an smp_wmb(), we should probably expand the
preemption-disabled section in kfence_protect_page() to cover the entire
function, to eliminate any risk that the PTE writes execute on a separate
CPU from the smp_wmb().
- Paul
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-10 0:59 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-29 9:25 [PATCH] riscv: mm: Fix concurrency in mark_new_valid_map() Vivian Wang
2026-07-10 0:59 ` Paul Walmsley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox