]> www.infradead.org Git - users/willy/xarray.git/commitdiff
riscv: vector: adjust minimum Vector requirement to ZVE32X
authorAndy Chiu <andy.chiu@sifive.com>
Thu, 9 May 2024 16:26:57 +0000 (00:26 +0800)
committerPalmer Dabbelt <palmer@rivosinc.com>
Thu, 30 May 2024 21:33:10 +0000 (14:33 -0700)
Make has_vector() to check for ZVE32X. Every in-kernel usage of V that
requires a more complicate version of V must then call out explicitly.

Also, change riscv_v_first_use_handler(), and boot code that calls
riscv_v_setup_vsize() to accept ZVE32X.

Most kernel/user interfaces requires minimum of ZVE32X. Thus, programs
compiled and run with ZVE32X should be supported by the kernel on most
aspects. This includes context-switch, signal, ptrace, prctl, and
hwprobe.

One exception is that ELF_HWCAP returns 'V' only if full V is supported
on the platform. This means that the system without a full V must not
rely on ELF_HWCAP to tell whether it is allowable to execute Vector
without first invoking a prctl() check.

Signed-off-by: Andy Chiu <andy.chiu@sifive.com>
Acked-by: Joel Granados <j.granados@samsung.com>
Link: https://lore.kernel.org/r/20240510-zve-detection-v5-7-0711bdd26c12@sifive.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/include/asm/vector.h
arch/riscv/kernel/cpufeature.c
arch/riscv/kernel/sys_hwprobe.c
arch/riscv/kernel/vector.c
arch/riscv/lib/uaccess.S

index 731dcd0ed4de92ac7a00b1e1c534b2c33d905d2d..be7d309cca8a78d3963ae42d4b55fda89b8ab9dc 100644 (file)
@@ -37,7 +37,7 @@ static inline u32 riscv_v_flags(void)
 
 static __always_inline bool has_vector(void)
 {
-       return riscv_has_extension_unlikely(RISCV_ISA_EXT_v);
+       return riscv_has_extension_unlikely(RISCV_ISA_EXT_ZVE32X);
 }
 
 static inline void __riscv_v_vstate_clean(struct pt_regs *regs)
@@ -91,7 +91,7 @@ static __always_inline void __vstate_csr_restore(struct __riscv_v_ext_state *src
 {
        asm volatile (
                ".option push\n\t"
-               ".option arch, +v\n\t"
+               ".option arch, +zve32x\n\t"
                "vsetvl  x0, %2, %1\n\t"
                ".option pop\n\t"
                "csrw   " __stringify(CSR_VSTART) ", %0\n\t"
@@ -109,7 +109,7 @@ static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
        __vstate_csr_save(save_to);
        asm volatile (
                ".option push\n\t"
-               ".option arch, +v\n\t"
+               ".option arch, +zve32x\n\t"
                "vsetvli        %0, x0, e8, m8, ta, ma\n\t"
                "vse8.v         v0, (%1)\n\t"
                "add            %1, %1, %0\n\t"
@@ -131,7 +131,7 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_
        riscv_v_enable();
        asm volatile (
                ".option push\n\t"
-               ".option arch, +v\n\t"
+               ".option arch, +zve32x\n\t"
                "vsetvli        %0, x0, e8, m8, ta, ma\n\t"
                "vle8.v         v0, (%1)\n\t"
                "add            %1, %1, %0\n\t"
@@ -153,7 +153,7 @@ static inline void __riscv_v_vstate_discard(void)
        riscv_v_enable();
        asm volatile (
                ".option push\n\t"
-               ".option arch, +v\n\t"
+               ".option arch, +zve32x\n\t"
                "vsetvli        %0, x0, e8, m8, ta, ma\n\t"
                "vmv.v.i        v0, -1\n\t"
                "vmv.v.i        v8, -1\n\t"
index 54a6f5357c763ae550231bc385e4cf0a1178d910..1d6e4fda00f885fc1fa9741ca7332d99d850d910 100644 (file)
@@ -724,11 +724,14 @@ void __init riscv_fill_hwcap(void)
                elf_hwcap &= ~COMPAT_HWCAP_ISA_F;
        }
 
-       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
+       if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZVE32X)) {
                /*
                 * This cannot fail when called on the boot hart
                 */
                riscv_v_setup_vsize();
+       }
+
+       if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
                /*
                 * ISA string in device tree might have 'v' flag, but
                 * CONFIG_RISCV_ISA_V is disabled in kernel.
index 35390b4a5a17291f2cd2882e25dc855f9aab5ec3..83fcc939df670a28c4aaa6cc69fb685ef1de117d 100644 (file)
@@ -69,7 +69,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
        if (riscv_isa_extension_available(NULL, c))
                pair->value |= RISCV_HWPROBE_IMA_C;
 
-       if (has_vector())
+       if (has_vector() && riscv_isa_extension_available(NULL, v))
                pair->value |= RISCV_HWPROBE_IMA_V;
 
        /*
@@ -113,6 +113,10 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
                EXT_KEY(ZICOND);
                EXT_KEY(ZIHINTPAUSE);
 
+               /*
+                * All the following extensions must depend on the kernel
+                * support of V.
+                */
                if (has_vector()) {
                        EXT_KEY(ZVE32X);
                        EXT_KEY(ZVE32F);
index 6727d1d3b8f282c16a161c96ba898a17db87176e..682b3feee45114694f29f2479bb7c75ce54e7e56 100644 (file)
@@ -173,8 +173,11 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
        u32 __user *epc = (u32 __user *)regs->epc;
        u32 insn = (u32)regs->badaddr;
 
+       if (!has_vector())
+               return false;
+
        /* Do not handle if V is not supported, or disabled */
-       if (!(ELF_HWCAP & COMPAT_HWCAP_ISA_V))
+       if (!riscv_v_vstate_ctrl_user_allowed())
                return false;
 
        /* If V has been enabled then it is not the first-use trap */
index 1399d797d81b08cf93c9877bf20dbf30b3dd38b6..6a9f116bb5459304cd2478ebe7c4755ebf612242 100644 (file)
@@ -14,7 +14,7 @@
 
 SYM_FUNC_START(__asm_copy_to_user)
 #ifdef CONFIG_RISCV_ISA_V
-       ALTERNATIVE("j fallback_scalar_usercopy", "nop", 0, RISCV_ISA_EXT_v, CONFIG_RISCV_ISA_V)
+       ALTERNATIVE("j fallback_scalar_usercopy", "nop", 0, RISCV_ISA_EXT_ZVE32X, CONFIG_RISCV_ISA_V)
        REG_L   t0, riscv_v_usercopy_threshold
        bltu    a2, t0, fallback_scalar_usercopy
        tail enter_vector_usercopy