[PATCH v2 10/10] riscv: hwprobe: Introduce rva23u64 base behavior
Guodong Xu
guodong at riscstar.com
Mon May 11 18:34:55 PDT 2026
Provide a hwprobe base-behavior bit so userspace can check RVA23U64
support in one call. Without it, a consumer needs five hwprobe
calls and four prctl calls, which is error-prone to require of every
caller. Most software treats RVA23U64 as a new base anyway, so
expose it directly.
Signed-off-by: Andrew Jones <andrew.jones at oss.qualcomm.com>
Signed-off-by: Guodong Xu <guodong at riscstar.com>
---
v2:
- Detect RVA23U64 by reading from the cached hart_isa[].isa_bases
bitmap populated by riscv_init_isa_bases() at init time, sharing
one source of truth with /proc/cpuinfo.
---
Documentation/arch/riscv/hwprobe.rst | 8 ++++++++
arch/riscv/include/uapi/asm/hwprobe.h | 3 ++-
arch/riscv/kernel/sys_hwprobe.c | 23 +++++++++++++++-------
tools/testing/selftests/riscv/hwprobe/which-cpus.c | 2 +-
4 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
index cb31fd3b12017..9b901bf8bab9a 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 0273f3c921b6 ("rva23/rvb23 ratified").
+
+ 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 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 430dc49a82863..d940ba4f6a1e8 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 dcc102bf8f183..c43fcad737b73 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -225,6 +225,17 @@ static bool hwprobe_ext0_has(const struct cpumask *cpus, u64 ext)
return (pair.value & ext);
}
+static bool hwprobe_has_isa_base(const struct cpumask *cpus, unsigned int base)
+{
+ int cpu;
+
+ for_each_cpu(cpu, cpus) {
+ if (!test_bit(base, hart_isa[cpu].isa_bases))
+ return false;
+ }
+ return true;
+}
+
#if defined(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS)
static u64 hwprobe_misaligned(const struct cpumask *cpus)
{
@@ -307,14 +318,12 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
case RISCV_HWPROBE_KEY_MIMPID:
hwprobe_arch_id(pair, cpus);
break;
- /*
- * The kernel already assumes that the base single-letter ISA
- * extensions are supported on all harts, and only supports the
- * IMA base, so just cheat a bit here and tell that to
- * userspace.
- */
case RISCV_HWPROBE_KEY_BASE_BEHAVIOR:
- pair->value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA;
+ pair->value = 0;
+ if (hwprobe_has_isa_base(cpus, RISCV_ISA_BASE_IMA))
+ pair->value |= RISCV_HWPROBE_BASE_BEHAVIOR_IMA;
+ if (hwprobe_has_isa_base(cpus, RISCV_ISA_BASE_RVA23U64))
+ 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 587feb198c049..f8c797b1d0fd9 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
More information about the linux-riscv
mailing list