[PATCH v2] riscv: hwprobe: fix has_fpu() to require D extension only

Ivy Lopez <[email protected]>
Newsgroups org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The kernel never supports F without D, since D depends on F. As such,
has_fpu() checking either extension with '||' is incorrect: it
reports FPU support when only F is present, which is not sufficient
for D-dependent state save/restore, and weakens
RISCV_HWPROBE_IMA_FD semantics to "F or D" instead of "F and D".

Fix has_fpu() to check D only, which is equivalent to requiring both
extensions given the dependency. Revert the explicit F && D check in
sys_hwprobe.c back to calling has_fpu(), which is now correct.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=221874
Suggested-by: Conor Dooley <[email protected]>
Suggested-by: Andreas Schwab <[email protected]>
Signed-off-by: Ivy Lopez <[email protected]>
---
Changes in v2:
- Original v1 approach (explicit F && D check in sys_hwprobe.c) was a
  no-op since F-without-D is structurally impossible. Per Conor and
  Andreas, fix has_fpu() itself instead, checking D only. Revert the
  sys_hwprobe.c change back to calling has_fpu().
- Link to v1: https://lore.kernel.org/r/[email protected]

 arch/riscv/include/asm/switch_to.h | 4 ++--
 arch/riscv/kernel/sys_hwprobe.c    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index 0e71eb82f920..8186cda88e17 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -60,8 +60,8 @@ static inline void __switch_to_fpu(struct task_struct *prev,
 
 static __always_inline bool has_fpu(void)
 {
-	return riscv_has_extension_likely(RISCV_ISA_EXT_f) ||
-		riscv_has_extension_likely(RISCV_ISA_EXT_d);
+	/* D extension depends on F, so checking D alone is sufficient. */
+	return riscv_has_extension_likely(RISCV_ISA_EXT_d);
 }
 #else
 static __always_inline bool has_fpu(void) { return false; }
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 7f91beb82a1c..1659d31fd288 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -85,7 +85,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 	u64 missing = 0;
 
 	pair->value = 0;
-	if (riscv_isa_extension_available(NULL, f) && riscv_isa_extension_available(NULL, d))
+	if (has_fpu())
 		pair->value |= RISCV_HWPROBE_IMA_FD;
 
 	if (riscv_isa_extension_available(NULL, c))
-- 
2.55.0


_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.