lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260206002349.96740-9-andrew.jones@oss.qualcomm.com>
Date: Thu,  5 Feb 2026 18:23:46 -0600
From: Andrew Jones <andrew.jones@....qualcomm.com>
To: linux-kernel@...r.kernel.org, linux-riscv@...ts.infradead.org,
        kvm-riscv@...ts.infradead.org
Cc: Paul Walmsley <pjw@...nel.org>, Palmer Dabbelt <palmer@...belt.com>,
        Anup Patel <anup@...infault.org>,
        Clément Léger <cleger@...osinc.com>,
        Conor Dooley <conor.dooley@...rochip.com>,
        Guodong Xu <guodong@...cstar.com>,
        Charlie Jenkins <charlie@...osinc.com>,
        Charlie Jenkins <thecharlesjenkins@...il.com>,
        Samuel Holland <samuel.holland@...ive.com>
Subject: [RFC PATCH v1 08/11] riscv: hwprobe: Introduce rva23u64 base behavior

Provide a bit to conveniently determine when RVA23U64 is supported.
While it's already possible to determine RVA23U64 support with five
hwprobe calls and four prctl calls it would be error-prone to require
anything (and we presume eventually almost everything) that needs to
check for RVA23U64 support to all implement those calls and specific
checks. And, while RVA23U64 is the IMA base with mandated extensions,
most software will consider it a new base. For these reasons, add
the RVA23U64 bit as a base behavior bit.

Signed-off-by: Andrew Jones <andrew.jones@....qualcomm.com>
---
 Documentation/arch/riscv/hwprobe.rst          |  8 +++
 arch/riscv/include/uapi/asm/hwprobe.h         |  3 +-
 arch/riscv/kernel/sys_hwprobe.c               | 72 +++++++++++++++++++
 .../selftests/riscv/hwprobe/which-cpus.c      |  2 +-
 4 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
index 97226b7c5936..6d915e7ba58a 100644
--- a/Documentation/arch/riscv/hwprobe.rst
+++ b/Documentation/arch/riscv/hwprobe.rst
@@ -67,6 +67,14 @@ The following keys are defined:
       programs (it may still be executed in userspace via a
       kernel-controlled mechanism such as the vDSO).
 
+  * :c:macro:`RISCV_HWPROBE_BASE_BEHAVIOR_RVA23U64`: Support for all mandatory
+    extensions of RVA23U64, as defined in the RISC-V Profiles specification
+    starting from commit b1d80660 ("Updated to ratified state.")
+
+    The RVA23U64 base is based upon the IMA base and therefore IMA extension
+    keys (e.g. :c:macro:`RISCV_HWPROBE_KEY_IMA_EXT_0`:) may be used to probe
+    optional extensions.
+
 * :c:macro:`RISCV_HWPROBE_KEY_IMA_EXT_0`: A bitmask containing the extensions
   that are compatible with the :c:macro:`RISCV_HWPROBE_BASE_BEHAVIOR_IMA`:
   base system behavior.
diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index fed9ea6fd2b5..72d2a4d0b733 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -21,7 +21,8 @@ struct riscv_hwprobe {
 #define RISCV_HWPROBE_KEY_MARCHID	1
 #define RISCV_HWPROBE_KEY_MIMPID	2
 #define RISCV_HWPROBE_KEY_BASE_BEHAVIOR	3
-#define		RISCV_HWPROBE_BASE_BEHAVIOR_IMA	(1 << 0)
+#define		RISCV_HWPROBE_BASE_BEHAVIOR_IMA		(1 << 0)
+#define		RISCV_HWPROBE_BASE_BEHAVIOR_RVA23U64	(1 << 1)
 #define RISCV_HWPROBE_KEY_IMA_EXT_0	4
 #define		RISCV_HWPROBE_IMA_FD		(1 << 0)
 #define		RISCV_HWPROBE_IMA_C		(1 << 1)
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 31d222301bf0..4b9981b15ebe 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -23,6 +23,7 @@
 #include <asm/vendor_extensions/thead_hwprobe.h>
 #include <vdso/vsyscall.h>
 
+extern bool riscv_have_user_pmlen_7;
 
 #define EXT_KEY(isa_arg, ext, pv, missing)					\
 	do {										\
@@ -222,6 +223,75 @@ static bool hwprobe_ext0_has(const struct cpumask *cpus, u64 ext)
 	return (pair.value & ext);
 }
 
+#define HWPROBE_EXT0_RVA23U64 (					\
+	/* IMA is always supported */				\
+	RISCV_HWPROBE_IMA_FD				|	\
+	RISCV_HWPROBE_IMA_C				|	\
+	/* B is Zba, Zbb and Zbs */				\
+	RISCV_HWPROBE_EXT_ZBA				|	\
+	RISCV_HWPROBE_EXT_ZBB				|	\
+	RISCV_HWPROBE_EXT_ZBS				|	\
+	/* ZICSR is always supported */				\
+	RISCV_HWPROBE_EXT_ZICNTR			|	\
+	RISCV_HWPROBE_EXT_ZIHPM				|	\
+	/* ZICCIF is in EXT1 */					\
+	/* ZICCRSE is in EXT1 */				\
+	/* ZICCAMOA is in EXT1 */				\
+	RISCV_HWPROBE_EXT_ZICCLSM			|	\
+	/* ZA64RS is in EXT1 */					\
+	RISCV_HWPROBE_EXT_ZIHINTPAUSE			|	\
+	/* ZIC64B (check block sizes are 64b) */		\
+	RISCV_HWPROBE_EXT_ZICBOM			|	\
+	RISCV_HWPROBE_EXT_ZICBOP			|	\
+	RISCV_HWPROBE_EXT_ZICBOZ			|	\
+	RISCV_HWPROBE_EXT_ZFHMIN			|	\
+	RISCV_HWPROBE_EXT_ZKT				|	\
+	RISCV_HWPROBE_IMA_V				|	\
+	RISCV_HWPROBE_EXT_ZVFHMIN			|	\
+	RISCV_HWPROBE_EXT_ZVBB				|	\
+	RISCV_HWPROBE_EXT_ZVKT				|	\
+	RISCV_HWPROBE_EXT_ZIHINTNTL			|	\
+	RISCV_HWPROBE_EXT_ZICOND			|	\
+	RISCV_HWPROBE_EXT_ZIMOP				|	\
+	RISCV_HWPROBE_EXT_ZCMOP				|	\
+	RISCV_HWPROBE_EXT_ZCB				|	\
+	RISCV_HWPROBE_EXT_ZFA				|	\
+	RISCV_HWPROBE_EXT_ZAWRS				|	\
+	RISCV_HWPROBE_EXT_SUPM /* (check PMLEN=7 support) */	\
+)
+
+#define HWPROBE_EXT1_RVA23U64 (					\
+	RISCV_HWPROBE_EXT_ZICCIF			|	\
+	RISCV_HWPROBE_EXT_ZICCRSE			|	\
+	RISCV_HWPROBE_EXT_ZICCAMOA			|	\
+	RISCV_HWPROBE_EXT_ZA64RS				\
+)
+
+static bool hwprobe_has_rva23u64(const struct cpumask *cpus)
+{
+	struct riscv_hwprobe pair;
+
+	if (!IS_ENABLED(CONFIG_64BIT))
+		return false;
+
+	/* Additional mandates for Zic64b and Supm */
+	if (riscv_cbom_block_size != 64 ||
+	    riscv_cbop_block_size != 64 ||
+	    riscv_cboz_block_size != 64 ||
+	    !riscv_have_user_pmlen_7)
+		return false;
+
+	hwprobe_isa_ext0(&pair, cpus);
+	if ((pair.value & HWPROBE_EXT0_RVA23U64) != HWPROBE_EXT0_RVA23U64)
+		return false;
+
+	hwprobe_isa_ext1(&pair, cpus);
+	if ((pair.value & HWPROBE_EXT1_RVA23U64) != HWPROBE_EXT1_RVA23U64)
+		return false;
+
+	return true;
+}
+
 #if defined(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS)
 static u64 hwprobe_misaligned(const struct cpumask *cpus)
 {
@@ -312,6 +382,8 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
 	 */
 	case RISCV_HWPROBE_KEY_BASE_BEHAVIOR:
 		pair->value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA;
+		if (hwprobe_has_rva23u64(cpus))
+			pair->value |= RISCV_HWPROBE_BASE_BEHAVIOR_RVA23U64;
 		break;
 
 	case RISCV_HWPROBE_KEY_IMA_EXT_0:
diff --git a/tools/testing/selftests/riscv/hwprobe/which-cpus.c b/tools/testing/selftests/riscv/hwprobe/which-cpus.c
index 587feb198c04..f8c797b1d0fd 100644
--- a/tools/testing/selftests/riscv/hwprobe/which-cpus.c
+++ b/tools/testing/selftests/riscv/hwprobe/which-cpus.c
@@ -105,7 +105,7 @@ int main(int argc, char **argv)
 	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR, };
 	rc = riscv_hwprobe(pairs, 1, 0, NULL, 0);
 	assert(rc == 0 && pairs[0].key == RISCV_HWPROBE_KEY_BASE_BEHAVIOR &&
-	       pairs[0].value == RISCV_HWPROBE_BASE_BEHAVIOR_IMA);
+	       (pairs[0].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA));
 
 	pairs[0] = (struct riscv_hwprobe){ .key = RISCV_HWPROBE_KEY_IMA_EXT_0, };
 	rc = riscv_hwprobe(pairs, 1, 0, NULL, 0);
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ