Hi,
On Sat, Jun 28, 2025 at 01:27:42AM +0800, Jingwei Wang wrote:
The value for some hwprobe keys, like MISALIGNED_VECTOR_PERF, is determined by an asynchronous kthread. This kthread can finish after the hwprobe vDSO data is populated, creating a race condition where userspace can read stale values.
A completion-based framework is introduced to synchronize the async probes with the vDSO population. The init_hwprobe_vdso_data() function is deferred to `late_initcall` and now blocks until all probes signal completion.
Reported-by: Tsukasa OI research_trasio@irq.a4lg.com Closes: https://lore.kernel.org/linux-riscv/760d637b-b13b-4518-b6bf-883d55d44e7f@irq... Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe") Cc: Palmer Dabbelt palmer@dabbelt.com Cc: Alexandre Ghiti alexghiti@rivosinc.com Cc: stable@vger.kernel.org Signed-off-by: Jingwei Wang wangjingwei@iscas.ac.cn
Changes in v4:
- Reworked the synchronization mechanism based on feedback from Palmer and Alexandre.
- Instead of a post-hoc refresh, this version introduces a robust
completion-based framework using an atomic counter to ensure async probes are finished before populating the vDSO.
- Moved the vdso data initialization to a late_initcall to avoid
impacting boot time.
Changes in v3:
- Retained existing blank line.
Changes in v2:
- Addressed feedback from Yixun's regarding #ifdef CONFIG_MMU usage.
- Updated commit message to provide a high-level summary.
- Added Fixes tag for commit e7c9d66e313b.
v1: https://lore.kernel.org/linux-riscv/20250521052754.185231-1-wangjingwei@isca...
arch/riscv/include/asm/hwprobe.h | 8 +++++++- arch/riscv/kernel/sys_hwprobe.c | 20 +++++++++++++++++++- arch/riscv/kernel/unaligned_access_speed.c | 9 +++++++-- 3 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h index 7fe0a379474ae2c6..87af186d92e75ddb 100644 --- a/arch/riscv/include/asm/hwprobe.h +++ b/arch/riscv/include/asm/hwprobe.h @@ -40,5 +40,11 @@ static inline bool riscv_hwprobe_pair_cmp(struct riscv_hwprobe *pair, return pair->value == other_pair->value; }
+#ifdef CONFIG_MMU +void riscv_hwprobe_register_async_probe(void); +void riscv_hwprobe_complete_async_probe(void); +#else +inline void riscv_hwprobe_register_async_probe(void) {} +inline void riscv_hwprobe_complete_async_probe(void) {}
These need to be:
static inline void riscv_hwprobe_register_async_probe(void) {} static inline void riscv_hwprobe_complete_async_probe(void) {}
Or else you get an global instantiation of them in every file that includes them, and compilation errors about duplicate symbols, as seen by nommu_virt_defconfig:
riscv64-linux-gnu-ld: arch/riscv/kernel/process.o: in function `riscv_hwprobe_register_async_probe': process.c:(.text+0x170): multiple definition of `riscv_hwprobe_register_async_probe'; arch/riscv/kernel/cpufeature.o:cpufeature.c:(.text+0x312): first defined here riscv64-linux-gnu-ld: arch/riscv/kernel/process.o: in function `riscv_hwprobe_complete_async_probe': process.c:(.text+0x17c): multiple definition of `riscv_hwprobe_complete_async_probe'; arch/riscv/kernel/cpufeature.o:cpufeature.c:(.text+0x31e): first defined here riscv64-linux-gnu-ld: arch/riscv/kernel/ptrace.o: in function `riscv_hwprobe_register_async_probe': ptrace.c:(.text+0x714): multiple definition of `riscv_hwprobe_register_async_probe'; arch/riscv/kernel/cpufeature.o:cpufeature.c:(.text+0x312): first defined here
-Olof