RISC-V: hwprobe: Expose Zba, Zbb, and Zbs
authorEvan Green <evan@rivosinc.com>
Tue, 9 May 2023 18:25:03 +0000 (11:25 -0700)
committerPalmer Dabbelt <palmer@rivosinc.com>
Mon, 19 Jun 2023 16:53:10 +0000 (09:53 -0700)
Add two new bits to the IMA_EXT_0 key for ZBA, ZBB, and ZBS extensions.
These are accurately reported per CPU.

Signed-off-by: Evan Green <evan@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
Link: https://lore.kernel.org/r/20230509182504.2997252-4-evan@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Documentation/riscv/hwprobe.rst
arch/riscv/include/uapi/asm/hwprobe.h
arch/riscv/kernel/sys_riscv.c

index 9f0dd62dcb5db66536c1b7272ae73be45888e2b6..fb25670ef0e5c5df91cacb27192d4343cba69573 100644 (file)
@@ -64,6 +64,16 @@ The following keys are defined:
   * :c:macro:`RISCV_HWPROBE_IMA_C`: The C extension is supported, as defined
     by version 2.2 of the RISC-V ISA manual.
 
+  * :c:macro:`RISCV_HWPROBE_EXT_ZBA`: The Zba address generation extension is
+       supported, as defined in version 1.0 of the Bit-Manipulation ISA
+       extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZBB`: The Zbb extension is supported, as defined
+       in version 1.0 of the Bit-Manipulation ISA extensions.
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZBS`: The Zbs extension is supported, as defined
+       in version 1.0 of the Bit-Manipulation ISA extensions.
+
 * :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: A bitmask that contains performance
   information about the selected set of processors.
 
index 8d745a4ad8a2c3e60ba09c0a93497711bd56f6e8..853f8f6d9a42032b17210a82aed2205b7979383f 100644 (file)
@@ -25,6 +25,9 @@ struct riscv_hwprobe {
 #define RISCV_HWPROBE_KEY_IMA_EXT_0    4
 #define                RISCV_HWPROBE_IMA_FD            (1 << 0)
 #define                RISCV_HWPROBE_IMA_C             (1 << 1)
+#define                RISCV_HWPROBE_EXT_ZBA           (1 << 2)
+#define                RISCV_HWPROBE_EXT_ZBB           (1 << 3)
+#define                RISCV_HWPROBE_EXT_ZBS           (1 << 4)
 #define RISCV_HWPROBE_KEY_CPUPERF_0    5
 #define                RISCV_HWPROBE_MISALIGNED_UNKNOWN        (0 << 0)
 #define                RISCV_HWPROBE_MISALIGNED_EMULATED       (1 << 0)
index 5db29683ebee7a8cb8c115f221178c947cbbc230..fe655db19ab4719b305ee5dd38befce7a6c736d0 100644 (file)
@@ -121,6 +121,46 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
        pair->value = id;
 }
 
+static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
+                            const struct cpumask *cpus)
+{
+       int cpu;
+       u64 missing = 0;
+
+       pair->value = 0;
+       if (has_fpu())
+               pair->value |= RISCV_HWPROBE_IMA_FD;
+
+       if (riscv_isa_extension_available(NULL, c))
+               pair->value |= RISCV_HWPROBE_IMA_C;
+
+       /*
+        * Loop through and record extensions that 1) anyone has, and 2) anyone
+        * doesn't have.
+        */
+       for_each_cpu(cpu, cpus) {
+               struct riscv_isainfo *isainfo = &hart_isa[cpu];
+
+               if (riscv_isa_extension_available(isainfo->isa, ZBA))
+                       pair->value |= RISCV_HWPROBE_EXT_ZBA;
+               else
+                       missing |= RISCV_HWPROBE_EXT_ZBA;
+
+               if (riscv_isa_extension_available(isainfo->isa, ZBB))
+                       pair->value |= RISCV_HWPROBE_EXT_ZBB;
+               else
+                       missing |= RISCV_HWPROBE_EXT_ZBB;
+
+               if (riscv_isa_extension_available(isainfo->isa, ZBS))
+                       pair->value |= RISCV_HWPROBE_EXT_ZBS;
+               else
+                       missing |= RISCV_HWPROBE_EXT_ZBS;
+       }
+
+       /* Now turn off reporting features if any CPU is missing it. */
+       pair->value &= ~missing;
+}
+
 static u64 hwprobe_misaligned(const struct cpumask *cpus)
 {
        int cpu;
@@ -164,13 +204,7 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
                break;
 
        case RISCV_HWPROBE_KEY_IMA_EXT_0:
-               pair->value = 0;
-               if (has_fpu())
-                       pair->value |= RISCV_HWPROBE_IMA_FD;
-
-               if (riscv_isa_extension_available(NULL, c))
-                       pair->value |= RISCV_HWPROBE_IMA_C;
-
+               hwprobe_isa_ext0(pair, cpus);
                break;
 
        case RISCV_HWPROBE_KEY_CPUPERF_0: