Merge tag 'riscv-for-linus-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / arch / riscv / kernel / sys_riscv.c
index b651ec698a91b11ff8f75ab402f33a1addbc66b5..c712037dbe10ec88b9ee8f5d8559f9b73c6608fa 100644 (file)
@@ -145,26 +145,38 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
        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;
+#define EXT_KEY(ext)                                                                   \
+       do {                                                                            \
+               if (__riscv_isa_extension_available(isainfo->isa, RISCV_ISA_EXT_##ext)) \
+                       pair->value |= RISCV_HWPROBE_EXT_##ext;                         \
+               else                                                                    \
+                       missing |= RISCV_HWPROBE_EXT_##ext;                             \
+       } while (false)
+
+               /*
+                * Only use EXT_KEY() for extensions which can be exposed to userspace,
+                * regardless of the kernel's configuration, as no other checks, besides
+                * presence in the hart_isa bitmap, are made.
+                */
+               EXT_KEY(ZBA);
+               EXT_KEY(ZBB);
+               EXT_KEY(ZBS);
+               EXT_KEY(ZICBOZ);
+#undef EXT_KEY
        }
 
        /* Now turn off reporting features if any CPU is missing it. */
        pair->value &= ~missing;
 }
 
+static bool hwprobe_ext0_has(const struct cpumask *cpus, unsigned long ext)
+{
+       struct riscv_hwprobe pair;
+
+       hwprobe_isa_ext0(&pair, cpus);
+       return (pair.value & ext);
+}
+
 static u64 hwprobe_misaligned(const struct cpumask *cpus)
 {
        int cpu;
@@ -215,6 +227,12 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
                pair->value = hwprobe_misaligned(cpus);
                break;
 
+       case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
+               pair->value = 0;
+               if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
+                       pair->value = riscv_cboz_block_size;
+               break;
+
        /*
         * For forward compatibility, unknown keys don't fail the whole
         * call, but get their element key set to -1 and value set to 0