[PATCH 3/6] riscv: hwprobe: Report Zicfilp and Zicfiss only when available

Radim Krčmář radim.krcmar at oss.qualcomm.com
Tue Oct 6 00:53:00 PDT 2026


User-mode use of Zicfilp and Zicfiss requires senvcfg.LPE and
senvcfg.SSE, respectively, which we set only when is_user_lpad_enabled()
and is_user_shstk_enabled() (CONFIG_RISCV_USER_CFI, the extension on all
harts, and not disabled by riscv_nousercfi).  hwprobe reports the
extensions from the per-hart ISA bitmaps alone, so it can advertise
extensions that are always disabled in user-mode.

Report correct environment to user-mode.

The changes to arch/riscv/include/asm/usercfi.h avoid
IS_ENABLED(CONFIG_RISCV_USER_CFI) guards in the conditions.

Fixes: 30c3099036a9 ("riscv/hwprobe: add zicfilp / zicfiss enumeration in hwprobe")
Signed-off-by: Radim Krčmář <radim.krcmar at oss.qualcomm.com>
---
 Cases where new harts fail to enable user cfi aren't curently handled
 very well.

 The rest of usercfi.h is currently using macros instead of inline
 functions, but I couldn't really bear to follow the same pattern...

 arch/riscv/include/asm/usercfi.h | 9 ++++++---
 arch/riscv/kernel/sys_hwprobe.c  | 9 +++++++--
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index 61ee02cee297..bbde171bccde 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -48,6 +48,8 @@ bool is_indir_lp_enabled(struct task_struct *task);
 bool is_indir_lp_locked(struct task_struct *task);
 void set_indir_lp_status(struct task_struct *task, bool enable);
 void set_indir_lp_lock(struct task_struct *task, bool lock);
+bool is_user_shstk_enabled(void);
+bool is_user_lpad_enabled(void);
 
 #define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK (PR_SHADOW_STACK_ENABLE)
 #define PR_CFI_SUPPORTED_STATUS_MASK (PR_CFI_ENABLE | PR_CFI_DISABLE | PR_CFI_LOCK)
@@ -88,10 +90,11 @@ void set_indir_lp_lock(struct task_struct *task, bool lock);
 
 #define get_active_shstk(task) 0UL
 
-#endif /* CONFIG_RISCV_USER_CFI */
+static __always_inline bool is_user_shstk_enabled(void) { return false; }
 
-bool is_user_shstk_enabled(void);
-bool is_user_lpad_enabled(void);
+static __always_inline bool is_user_lpad_enabled(void) { return false; }
+
+#endif /* CONFIG_RISCV_USER_CFI */
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index c74e36e8fcdd..477d8fd780a6 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -14,6 +14,7 @@
 #include <asm/switch_to.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include <asm/usercfi.h>
 #include <asm/vector.h>
 #include <asm/vendor_extensions/mips_hwprobe.h>
 #include <asm/vendor_extensions/sifive_hwprobe.h>
@@ -97,6 +98,9 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 	if (riscv_isa_extension_available(NULL, ZICBOZ))
 		pair->value |= RISCV_HWPROBE_EXT_ZICBOZ;
 
+	if (is_user_lpad_enabled())
+		pair->value |= RISCV_HWPROBE_EXT_ZICFILP;
+
 	/*
 	 * Loop through and record extensions that 1) anyone has, and 2) anyone
 	 * doesn't have.
@@ -127,7 +131,6 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 		EXT_KEY(isainfo->isa, ZCLSD, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZCMOP, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZICBOP, pair->value, missing);
-		EXT_KEY(isainfo->isa, ZICFILP, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZICNTR, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZICOND, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZIHINTNTL, pair->value, missing);
@@ -197,6 +200,9 @@ static void hwprobe_isa_ext1(struct riscv_hwprobe *pair,
 
 	pair->value = 0;
 
+	if (is_user_shstk_enabled())
+		pair->value |= RISCV_HWPROBE_EXT_ZICFISS;
+
 	/*
 	 * Loop through and record extensions that 1) anyone has, and 2) anyone
 	 * doesn't have.
@@ -210,7 +216,6 @@ static void hwprobe_isa_ext1(struct riscv_hwprobe *pair,
 		 * configuration, as no other checks, besides presence
 		 * in the hart_isa bitmap, are made.
 		 */
-		EXT_KEY(isainfo->isa, ZICFISS, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZICCLSM, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZICCAMOA, pair->value, missing);
 		EXT_KEY(isainfo->isa, ZICCIF, pair->value, missing);
-- 
2.55.0




More information about the linux-riscv mailing list