linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] riscv: hwprobe: Fix stale vDSO data for late-initialized keys at boot
@ 2025-05-21  5:27 wangjingwei
  2025-05-21  7:52 ` Yixun Lan
  0 siblings, 1 reply; 3+ messages in thread
From: wangjingwei @ 2025-05-21  5:27 UTC (permalink / raw)
  To: linux-riscv
  Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Andrew Jones, Conor Dooley, Clément Léger,
	Charlie Jenkins, Tsukasa OI, Jingwei Wang

From: Jingwei Wang <wangjingwei@iscas.ac.cn>

The riscv_hwprobe vDSO data is populated by init_hwprobe_vdso_data(),
an arch_initcall_sync. However, underlying data for some keys, like
RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, is determined asynchronously.

Specifically, the per_cpu(vector_misaligned_access, cpu) values are set
by the vec_check_unaligned_access_speed_all_cpus kthread. This kthread
is spawned by an earlier arch_initcall (check_unaligned_access_all_cpus)
and may complete its benchmark *after* init_hwprobe_vdso_data() has
already populated the vDSO with default/stale values.

This patch introduces riscv_hwprobe_vdso_sync(sync_key). This function
is now called by the vec_check_unaligned_access_speed_all_cpus kthread
upon its completion. It re-evaluates the specified key using current kernel
state (including the finalized per-CPU data) via hwprobe_one_pair()
and updates the corresponding entry in vdso_k_arch_data.

This ensures the vDSO accurately reflects the final boot-time values
for keys determined by such asynchronous boot tasks, resolving observed
inconsistencies when userspace starts.

Test by comparing vDSO and syscall results for affected keys
(e.g., MISALIGNED_VECTOR_PERF), which now match their final
boot-time values.

Reported-by: Tsukasa OI <research_trasio@irq.a4lg.com>
Closes: https://lore.kernel.org/linux-riscv/760d637b-b13b-4518-b6bf-883d55d44e7f@irq.a4lg.com/
Signed-off-by: Jingwei Wang <wangjingwei@iscas.ac.cn>
---
 arch/riscv/include/asm/hwprobe.h           |  4 ++++
 arch/riscv/kernel/sys_hwprobe.c            | 16 ++++++++++++++++
 arch/riscv/kernel/unaligned_access_speed.c |  4 +++-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
index 1f690fea0e03de6a..02c34f03d8b9bc83 100644
--- a/arch/riscv/include/asm/hwprobe.h
+++ b/arch/riscv/include/asm/hwprobe.h
@@ -40,4 +40,8 @@ static inline bool riscv_hwprobe_pair_cmp(struct riscv_hwprobe *pair,
 	return pair->value == other_pair->value;
 }
 
+#ifdef CONFIG_MMU
+void riscv_hwprobe_vdso_sync(s64 sync_key);
+#endif /* CONFIG_MMU */
+
 #endif
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 249aec8594a92a80..c2593bd766055d35 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -17,6 +17,7 @@
 #include <asm/vector.h>
 #include <asm/vendor_extensions/thead_hwprobe.h>
 #include <vdso/vsyscall.h>
+#include <vdso/datapage.h>
 
 
 static void hwprobe_arch_id(struct riscv_hwprobe *pair,
@@ -500,6 +501,21 @@ static int __init init_hwprobe_vdso_data(void)
 
 arch_initcall_sync(init_hwprobe_vdso_data);
 
+void riscv_hwprobe_vdso_sync(s64 sync_key)
+{
+	struct vdso_arch_data *avd = vdso_k_arch_data;
+	struct riscv_hwprobe pair;
+
+	pair.key = sync_key;
+	hwprobe_one_pair(&pair, cpu_online_mask);
+	/*
+	 * Update vDSO data for the given key.
+	 * Currently for non-ID key updates (e.g. MISALIGNED_VECTOR_PERF),
+	 * so 'homogeneous_cpus' is not re-evaluated here.
+	 */
+	avd->all_cpu_hwprobe_values[sync_key] = pair.value;
+}
+
 #endif /* CONFIG_MMU */
 
 SYSCALL_DEFINE5(riscv_hwprobe, struct riscv_hwprobe __user *, pairs,
diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
index 585d2dcf2dab1ccb..7194aee3bf3234e5 100644
--- a/arch/riscv/kernel/unaligned_access_speed.c
+++ b/arch/riscv/kernel/unaligned_access_speed.c
@@ -375,7 +375,9 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
 static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
 {
 	schedule_on_each_cpu(check_vector_unaligned_access);
-
+#ifdef CONFIG_MMU
+	riscv_hwprobe_vdso_sync(RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF);
+#endif
 	return 0;
 }
 #else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
-- 
2.49.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] riscv: hwprobe: Fix stale vDSO data for late-initialized keys at boot
  2025-05-21  5:27 [PATCH] riscv: hwprobe: Fix stale vDSO data for late-initialized keys at boot wangjingwei
@ 2025-05-21  7:52 ` Yixun Lan
  2025-05-22  1:40   ` 王经纬
  0 siblings, 1 reply; 3+ messages in thread
From: Yixun Lan @ 2025-05-21  7:52 UTC (permalink / raw)
  To: wangjingwei
  Cc: linux-riscv, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Andrew Jones, Conor Dooley,
	Clément Léger, Charlie Jenkins, Tsukasa OI

Hi Jingwei,

On 13:27 Wed 21 May     , wangjingwei@iscas.ac.cn wrote:
> From: Jingwei Wang <wangjingwei@iscas.ac.cn>
> 
> The riscv_hwprobe vDSO data is populated by init_hwprobe_vdso_data(),
> an arch_initcall_sync. However, underlying data for some keys, like
> RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, is determined asynchronously.
> 
> Specifically, the per_cpu(vector_misaligned_access, cpu) values are set
> by the vec_check_unaligned_access_speed_all_cpus kthread. This kthread
> is spawned by an earlier arch_initcall (check_unaligned_access_all_cpus)
> and may complete its benchmark *after* init_hwprobe_vdso_data() has
> already populated the vDSO with default/stale values.
> 
> This patch introduces riscv_hwprobe_vdso_sync(sync_key). This function
> is now called by the vec_check_unaligned_access_speed_all_cpus kthread
> upon its completion. It re-evaluates the specified key using current kernel
> state (including the finalized per-CPU data) via hwprobe_one_pair()
> and updates the corresponding entry in vdso_k_arch_data.
> 
Personally, it's unnecessary to explain the patch line by line, 
giving a high level summary would be great

> This ensures the vDSO accurately reflects the final boot-time values
> for keys determined by such asynchronous boot tasks, resolving observed
> inconsistencies when userspace starts.
> 
> Test by comparing vDSO and syscall results for affected keys
> (e.g., MISALIGNED_VECTOR_PERF), which now match their final
> boot-time values.
> 
> Reported-by: Tsukasa OI <research_trasio@irq.a4lg.com>
> Closes: https://lore.kernel.org/linux-riscv/760d637b-b13b-4518-b6bf-883d55d44e7f@irq.a4lg.com/
As you give a Closes tag here, so I'd ask

Can you check which commit introduced this problem? it might warrant
a Fixes tag, please also CC stable if needed

(Check the kernel commit log for what's format of Fixes tag,
 12 charactors for hash + full commit title)

> Signed-off-by: Jingwei Wang <wangjingwei@iscas.ac.cn>
> ---
>  arch/riscv/include/asm/hwprobe.h           |  4 ++++
>  arch/riscv/kernel/sys_hwprobe.c            | 16 ++++++++++++++++
>  arch/riscv/kernel/unaligned_access_speed.c |  4 +++-
>  3 files changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
> index 1f690fea0e03de6a..02c34f03d8b9bc83 100644
> --- a/arch/riscv/include/asm/hwprobe.h
> +++ b/arch/riscv/include/asm/hwprobe.h
> @@ -40,4 +40,8 @@ static inline bool riscv_hwprobe_pair_cmp(struct riscv_hwprobe *pair,
>  	return pair->value == other_pair->value;
>  }
>  
> +#ifdef CONFIG_MMU
> +void riscv_hwprobe_vdso_sync(s64 sync_key);
> +#endif /* CONFIG_MMU */
> +
we usually try to avoid repeat "#ifdef CONFIG_MMU" in header & c file (unaligned_access_speed.c)
so, you can do

#ifdef CONFIG_MMU
void riscv_hwprobe_vdso_sync(s64 sync_key);
#else
static inline void riscv_hwprobe_vdso_sync(s64 sync_key) { };
#endif /* CONFIG_MMU */


>  #endif
> diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
> index 249aec8594a92a80..c2593bd766055d35 100644
> --- a/arch/riscv/kernel/sys_hwprobe.c
> +++ b/arch/riscv/kernel/sys_hwprobe.c
> @@ -17,6 +17,7 @@
>  #include <asm/vector.h>
>  #include <asm/vendor_extensions/thead_hwprobe.h>
>  #include <vdso/vsyscall.h>
> +#include <vdso/datapage.h>
>  
>  
>  static void hwprobe_arch_id(struct riscv_hwprobe *pair,
> @@ -500,6 +501,21 @@ static int __init init_hwprobe_vdso_data(void)
>  
>  arch_initcall_sync(init_hwprobe_vdso_data);
>  
> +void riscv_hwprobe_vdso_sync(s64 sync_key)
> +{
> +	struct vdso_arch_data *avd = vdso_k_arch_data;
> +	struct riscv_hwprobe pair;
> +
> +	pair.key = sync_key;
> +	hwprobe_one_pair(&pair, cpu_online_mask);
> +	/*
> +	 * Update vDSO data for the given key.
> +	 * Currently for non-ID key updates (e.g. MISALIGNED_VECTOR_PERF),
> +	 * so 'homogeneous_cpus' is not re-evaluated here.
> +	 */
> +	avd->all_cpu_hwprobe_values[sync_key] = pair.value;
> +}
> +
>  #endif /* CONFIG_MMU */
>  
>  SYSCALL_DEFINE5(riscv_hwprobe, struct riscv_hwprobe __user *, pairs,
> diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
> index 585d2dcf2dab1ccb..7194aee3bf3234e5 100644
> --- a/arch/riscv/kernel/unaligned_access_speed.c
> +++ b/arch/riscv/kernel/unaligned_access_speed.c
> @@ -375,7 +375,9 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
>  static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
>  {
>  	schedule_on_each_cpu(check_vector_unaligned_access);
> -
> +#ifdef CONFIG_MMU
> +	riscv_hwprobe_vdso_sync(RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF);
> +#endif
>  	return 0;
>  }
>  #else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
> -- 
> 2.49.0
> 
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

-- 
Yixun Lan (dlan)

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Re: [PATCH] riscv: hwprobe: Fix stale vDSO data for late-initialized keys at boot
  2025-05-21  7:52 ` Yixun Lan
@ 2025-05-22  1:40   ` 王经纬
  0 siblings, 0 replies; 3+ messages in thread
From: 王经纬 @ 2025-05-22  1:40 UTC (permalink / raw)
  To: Yixun Lan
  Cc: linux-riscv, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Andrew Jones, Conor Dooley,
	Clément Léger, Charlie Jenkins, Tsukasa OI




&gt; -----原始邮件-----
&gt; 发件人: "Yixun Lan" <dlan@gentoo.org>
&gt; 发送时间: 2025-05-21 15:52:35 (星期三)
&gt; 收件人: wangjingwei@iscas.ac.cn
&gt; 抄送: linux-riscv@lists.infradead.org, "Paul Walmsley" <paul.walmsley@sifive.com>, "Palmer Dabbelt" <palmer@dabbelt.com>, "Albert Ou" <aou@eecs.berkeley.edu>, "Alexandre Ghiti" <alex@ghiti.fr>, "Andrew Jones" <ajones@ventanamicro.com>, "Conor Dooley" <conor.dooley@microchip.com>, "Clément Léger" <cleger@rivosinc.com>, "Charlie Jenkins" <charlie@rivosinc.com>, "Tsukasa OI" <research_trasio@irq.a4lg.com>
&gt; 主题: Re: [PATCH] riscv: hwprobe: Fix stale vDSO data for late-initialized keys at boot
&gt; 
&gt; Hi Jingwei,
&gt; 
&gt; On 13:27 Wed 21 May     , wangjingwei@iscas.ac.cn wrote:
&gt; &gt; From: Jingwei Wang <wangjingwei@iscas.ac.cn>
&gt; &gt; 
&gt; &gt; The riscv_hwprobe vDSO data is populated by init_hwprobe_vdso_data(),
&gt; &gt; an arch_initcall_sync. However, underlying data for some keys, like
&gt; &gt; RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, is determined asynchronously.
&gt; &gt; 
&gt; &gt; Specifically, the per_cpu(vector_misaligned_access, cpu) values are set
&gt; &gt; by the vec_check_unaligned_access_speed_all_cpus kthread. This kthread
&gt; &gt; is spawned by an earlier arch_initcall (check_unaligned_access_all_cpus)
&gt; &gt; and may complete its benchmark *after* init_hwprobe_vdso_data() has
&gt; &gt; already populated the vDSO with default/stale values.
&gt; &gt; 
&gt; &gt; This patch introduces riscv_hwprobe_vdso_sync(sync_key). This function
&gt; &gt; is now called by the vec_check_unaligned_access_speed_all_cpus kthread
&gt; &gt; upon its completion. It re-evaluates the specified key using current kernel
&gt; &gt; state (including the finalized per-CPU data) via hwprobe_one_pair()
&gt; &gt; and updates the corresponding entry in vdso_k_arch_data.
&gt; &gt; 
&gt; Personally, it's unnecessary to explain the patch line by line, 
&gt; giving a high level summary would be great
&gt; 
&gt; &gt; This ensures the vDSO accurately reflects the final boot-time values
&gt; &gt; for keys determined by such asynchronous boot tasks, resolving observed
&gt; &gt; inconsistencies when userspace starts.
&gt; &gt; 
&gt; &gt; Test by comparing vDSO and syscall results for affected keys
&gt; &gt; (e.g., MISALIGNED_VECTOR_PERF), which now match their final
&gt; &gt; boot-time values.
&gt; &gt; 
&gt; &gt; Reported-by: Tsukasa OI <research_trasio@irq.a4lg.com>
&gt; &gt; Closes: https://lore.kernel.org/linux-riscv/760d637b-b13b-4518-b6bf-883d55d44e7f@irq.a4lg.com/
&gt; As you give a Closes tag here, so I'd ask
&gt; 
&gt; Can you check which commit introduced this problem? it might warrant
&gt; a Fixes tag, please also CC stable if needed
&gt; 
&gt; (Check the kernel commit log for what's format of Fixes tag,
&gt;  12 charactors for hash + full commit title)
&gt; 
&gt; &gt; Signed-off-by: Jingwei Wang <wangjingwei@iscas.ac.cn>
&gt; &gt; ---
&gt; &gt;  arch/riscv/include/asm/hwprobe.h           |  4 ++++
&gt; &gt;  arch/riscv/kernel/sys_hwprobe.c            | 16 ++++++++++++++++
&gt; &gt;  arch/riscv/kernel/unaligned_access_speed.c |  4 +++-
&gt; &gt;  3 files changed, 23 insertions(+), 1 deletion(-)
&gt; &gt; 
&gt; &gt; diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
&gt; &gt; index 1f690fea0e03de6a..02c34f03d8b9bc83 100644
&gt; &gt; --- a/arch/riscv/include/asm/hwprobe.h
&gt; &gt; +++ b/arch/riscv/include/asm/hwprobe.h
&gt; &gt; @@ -40,4 +40,8 @@ static inline bool riscv_hwprobe_pair_cmp(struct riscv_hwprobe *pair,
&gt; &gt;  	return pair-&gt;value == other_pair-&gt;value;
&gt; &gt;  }
&gt; &gt;  
&gt; &gt; +#ifdef CONFIG_MMU
&gt; &gt; +void riscv_hwprobe_vdso_sync(s64 sync_key);
&gt; &gt; +#endif /* CONFIG_MMU */
&gt; &gt; +
&gt; we usually try to avoid repeat "#ifdef CONFIG_MMU" in header &amp; c file (unaligned_access_speed.c)
&gt; so, you can do
&gt; 
&gt; #ifdef CONFIG_MMU
&gt; void riscv_hwprobe_vdso_sync(s64 sync_key);
&gt; #else
&gt; static inline void riscv_hwprobe_vdso_sync(s64 sync_key) { };
&gt; #endif /* CONFIG_MMU */
&gt; 
&gt; 
&gt; &gt;  #endif
&gt; &gt; diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
&gt; &gt; index 249aec8594a92a80..c2593bd766055d35 100644
&gt; &gt; --- a/arch/riscv/kernel/sys_hwprobe.c
&gt; &gt; +++ b/arch/riscv/kernel/sys_hwprobe.c
&gt; &gt; @@ -17,6 +17,7 @@
&gt; &gt;  #include <asm vector.h="">
&gt; &gt;  #include <asm vendor_extensions="" thead_hwprobe.h="">
&gt; &gt;  #include <vdso vsyscall.h="">
&gt; &gt; +#include <vdso datapage.h="">
&gt; &gt;  
&gt; &gt;  
&gt; &gt;  static void hwprobe_arch_id(struct riscv_hwprobe *pair,
&gt; &gt; @@ -500,6 +501,21 @@ static int __init init_hwprobe_vdso_data(void)
&gt; &gt;  
&gt; &gt;  arch_initcall_sync(init_hwprobe_vdso_data);
&gt; &gt;  
&gt; &gt; +void riscv_hwprobe_vdso_sync(s64 sync_key)
&gt; &gt; +{
&gt; &gt; +	struct vdso_arch_data *avd = vdso_k_arch_data;
&gt; &gt; +	struct riscv_hwprobe pair;
&gt; &gt; +
&gt; &gt; +	pair.key = sync_key;
&gt; &gt; +	hwprobe_one_pair(&amp;pair, cpu_online_mask);
&gt; &gt; +	/*
&gt; &gt; +	 * Update vDSO data for the given key.
&gt; &gt; +	 * Currently for non-ID key updates (e.g. MISALIGNED_VECTOR_PERF),
&gt; &gt; +	 * so 'homogeneous_cpus' is not re-evaluated here.
&gt; &gt; +	 */
&gt; &gt; +	avd-&gt;all_cpu_hwprobe_values[sync_key] = pair.value;
&gt; &gt; +}
&gt; &gt; +
&gt; &gt;  #endif /* CONFIG_MMU */
&gt; &gt;  
&gt; &gt;  SYSCALL_DEFINE5(riscv_hwprobe, struct riscv_hwprobe __user *, pairs,
&gt; &gt; diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
&gt; &gt; index 585d2dcf2dab1ccb..7194aee3bf3234e5 100644
&gt; &gt; --- a/arch/riscv/kernel/unaligned_access_speed.c
&gt; &gt; +++ b/arch/riscv/kernel/unaligned_access_speed.c
&gt; &gt; @@ -375,7 +375,9 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
&gt; &gt;  static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
&gt; &gt;  {
&gt; &gt;  	schedule_on_each_cpu(check_vector_unaligned_access);
&gt; &gt; -
&gt; &gt; +#ifdef CONFIG_MMU
&gt; &gt; +	riscv_hwprobe_vdso_sync(RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF);
&gt; &gt; +#endif
&gt; &gt;  	return 0;
&gt; &gt;  }
&gt; &gt;  #else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
&gt; &gt; -- 
&gt; &gt; 2.49.0
&gt; &gt; 
&gt; &gt; 
&gt; &gt; _______________________________________________
&gt; &gt; linux-riscv mailing list
&gt; &gt; linux-riscv@lists.infradead.org
&gt; &gt; http://lists.infradead.org/mailman/listinfo/linux-riscv
&gt; 
&gt; -- 
&gt; Yixun Lan (dlan)

Thanks Yixun, I'll address these points in v2.


</vdso></vdso></asm></asm></wangjingwei@iscas.ac.cn></research_trasio@irq.a4lg.com></wangjingwei@iscas.ac.cn></research_trasio@irq.a4lg.com></charlie@rivosinc.com></cleger@rivosinc.com></conor.dooley@microchip.com></ajones@ventanamicro.com></alex@ghiti.fr></aou@eecs.berkeley.edu></palmer@dabbelt.com></paul.walmsley@sifive.com></dlan@gentoo.org>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-05-22  1:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-21  5:27 [PATCH] riscv: hwprobe: Fix stale vDSO data for late-initialized keys at boot wangjingwei
2025-05-21  7:52 ` Yixun Lan
2025-05-22  1:40   ` 王经纬

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).