Merge tag 'riscv-for-linus-6.9-mw2' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / arch / riscv / kernel / cpufeature.c
index afeae3ff43dc1f880594708444121b823ba8d7ce..3ed2359eae353f863561c02983e4e5e5bf27603d 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/hwcap.h>
 #include <asm/patch.h>
 #include <asm/processor.h>
+#include <asm/sbi.h>
 #include <asm/vector.h>
 
 #define NUM_ALPHA_EXTS ('z' - 'a' + 1)
@@ -187,6 +188,16 @@ static const unsigned int riscv_zvbb_exts[] = {
        RISCV_ISA_EXT_ZVKB
 };
 
+/*
+ * While the [ms]envcfg CSRs were not defined until version 1.12 of the RISC-V
+ * privileged ISA, the existence of the CSRs is implied by any extension which
+ * specifies [ms]envcfg bit(s). Hence, we define a custom ISA extension for the
+ * existence of the CSR, and treat it as a subset of those other extensions.
+ */
+static const unsigned int riscv_xlinuxenvcfg_exts[] = {
+       RISCV_ISA_EXT_XLINUXENVCFG
+};
+
 /*
  * The canonical order of ISA extension names in the ISA string is defined in
  * chapter 27 of the unprivileged specification.
@@ -236,8 +247,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
        __RISCV_ISA_EXT_DATA(c, RISCV_ISA_EXT_c),
        __RISCV_ISA_EXT_DATA(v, RISCV_ISA_EXT_v),
        __RISCV_ISA_EXT_DATA(h, RISCV_ISA_EXT_h),
-       __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
-       __RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ),
+       __RISCV_ISA_EXT_SUPERSET(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts),
+       __RISCV_ISA_EXT_SUPERSET(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts),
        __RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
        __RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
        __RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR),
@@ -525,6 +536,20 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
                        set_bit(RISCV_ISA_EXT_ZIHPM, isainfo->isa);
                }
 
+               /*
+                * "V" in ISA strings is ambiguous in practice: it should mean
+                * just the standard V-1.0 but vendors aren't well behaved.
+                * Many vendors with T-Head CPU cores which implement the 0.7.1
+                * version of the vector specification put "v" into their DTs.
+                * CPU cores with the ratified spec will contain non-zero
+                * marchid.
+                */
+               if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID &&
+                   riscv_cached_marchid(cpu) == 0x0) {
+                       this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
+                       clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
+               }
+
                /*
                 * All "okay" hart should have same isa. Set HWCAP based on
                 * common capabilities of every "okay" hart, in case they don't
@@ -696,7 +721,7 @@ unsigned long riscv_get_elf_hwcap(void)
 void riscv_user_isa_enable(void)
 {
        if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
-               csr_set(CSR_SENVCFG, ENVCFG_CBZE);
+               csr_set(CSR_ENVCFG, ENVCFG_CBZE);
 }
 
 #ifdef CONFIG_RISCV_ALTERNATIVE