@@ -520,60 +520,6 @@ config RISCV_ISA_SVPBMT
If you don't know what to do here, say Y.
-config TOOLCHAIN_HAS_V
- bool
- default y
- depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv)
- depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv)
- depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800
- depends on AS_HAS_OPTION_ARCH
-
-config RISCV_ISA_V
- bool "Vector extension support"
- depends on TOOLCHAIN_HAS_V
- depends on FPU
- select DYNAMIC_SIGFRAME
- default y
- help
- Add support for the Vector extension when it is detected at boot.
- When this option is disabled, neither the kernel nor userspace may
- use vector procedures.
-
- If you don't know what to do here, say Y.
-
-config RISCV_ISA_V_DEFAULT_ENABLE
- bool "Enable userspace Vector by default"
- depends on RISCV_ISA_V
- default y
- help
- Say Y here if you want to enable Vector in userspace by default.
- Otherwise, userspace has to make explicit prctl() call to enable
- Vector, or enable it via the sysctl interface.
-
- If you don't know what to do here, say Y.
-
-config RISCV_ISA_V_UCOPY_THRESHOLD
- int "Threshold size for vectorized user copies"
- depends on RISCV_ISA_V
- default 768
- help
- Prefer using vectorized copy_to_user()/copy_from_user() when the
- workload size exceeds this value.
-
-config RISCV_ISA_V_PREEMPTIVE
- bool "Run kernel-mode Vector with kernel preemption"
- depends on PREEMPTION
- depends on RISCV_ISA_V
- default y
- help
- Usually, in-kernel SIMD routines are run with preemption disabled.
- Functions which envoke long running SIMD thus must yield core's
- vector unit to prevent blocking other tasks for too long.
-
- This config allows kernel to run SIMD without explicitly disable
- preemption. Enabling this config will result in higher memory
- consumption due to the allocation of per-task's kernel Vector context.
-
config TOOLCHAIN_HAS_ZBB
bool
default y
@@ -39,3 +39,88 @@ config PLATFORM_SUPPORTS_RISCV_ISA_C
If you don't know what to do here, say Y.
endchoice
+
+config TOOLCHAIN_HAS_V
+ bool
+ default y
+ depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv)
+ depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv)
+ depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800
+ depends on AS_HAS_OPTION_ARCH
+
+config RISCV_ISA_V
+ bool
+
+choice
+ prompt "Vector extension support"
+ default PLATFORM_MAY_SUPPORT_RISCV_ISA_V
+ help
+ This selects the level of support for vector instructions to be
+ built into the Linux Kernel. This does not impact whether vector
+ instructions are allowed to be emitted by user-space code.
+
+config PROHIBIT_RISCV_ISA_V
+ bool "Prohibit vector instructions"
+ depends on NONPORTABLE
+ help
+ Regardless of if the platform supports vector instructions,
+ prohibit the kernel from emitting vector instructions.
+
+config PLATFORM_MAY_SUPPORT_RISCV_ISA_V
+ bool "Allow vector instruction sequences if supported"
+ depends on TOOLCHAIN_HAS_V
+ depends on FPU
+ select DYNAMIC_SIGFRAME
+ select RISCV_ISA_V
+ help
+ Only allow vector instructions to be emitted if "V" is present in
+ the device tree or ACPI table. No vector instructions will be
+ emitted if the platform does not support them.
+
+config PLATFORM_SUPPORTS_RISCV_ISA_V
+ bool "Emit vector instructions when building Linux"
+ depends on TOOLCHAIN_HAS_V
+ depends on FPU
+ depends on NONPORTABLE
+ select DYNAMIC_SIGFRAME
+ select RISCV_ISA_V
+ help
+ Adds "V" to the ISA subsets that the toolchain is allowed to emit
+ when building Linux, which results in vector instructions in the
+ Linux binary. This option produces a kernel that will not run on
+ systems that do not support vector instructions.
+
+endchoice
+
+config RISCV_ISA_V_DEFAULT_ENABLE
+ bool "Enable userspace Vector by default"
+ depends on RISCV_ISA_V
+ default y
+ help
+ Say Y here if you want to enable Vector in userspace by default.
+ Otherwise, userspace has to make explicit prctl() call to enable
+ Vector, or enable it via the sysctl interface.
+
+ If you don't know what to do here, say Y.
+
+config RISCV_ISA_V_UCOPY_THRESHOLD
+ int "Threshold size for vectorized user copies"
+ depends on RISCV_ISA_V
+ default 768
+ help
+ Prefer using vectorized copy_to_user()/copy_from_user() when the
+ workload size exceeds this value.
+
+config RISCV_ISA_V_PREEMPTIVE
+ bool "Run kernel-mode Vector with kernel preemption"
+ depends on PREEMPTION
+ depends on RISCV_ISA_V
+ default y
+ help
+ Usually, in-kernel SIMD routines are run with preemption disabled.
+ Functions which envoke long running SIMD thus must yield core's
+ vector unit to prevent blocking other tasks for too long.
+
+ This config allows kernel to run SIMD without explicitly disable
+ preemption. Enabling this config will result in higher memory
+ consumption due to the allocation of per-task's kernel Vector context.
@@ -66,7 +66,6 @@ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
riscv-march-$(CONFIG_PLATFORM_SUPPORTS_RISCV_ISA_C) := $(riscv-march-y)c
-riscv-march-$(CONFIG_RISCV_ISA_V) := $(riscv-march-y)v
ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC
KBUILD_CFLAGS += -Wa,-misa-spec=2.2
@@ -78,10 +77,7 @@ endif
# Check if the toolchain supports Zihintpause extension
riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
-# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
-# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
-KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
-
+KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
KBUILD_AFLAGS += -march=$(riscv-march-y)
KBUILD_CFLAGS += -mno-save-restore
@@ -4,7 +4,7 @@ menu "Accelerated Cryptographic Algorithms for CPU (riscv)"
config CRYPTO_AES_RISCV64
tristate "Ciphers: AES, modes: ECB, CBC, CTS, CTR, XTS"
- depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ depends on 64BIT && PLATFORM_SUPPORTS_RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
select CRYPTO_ALGAPI
select CRYPTO_LIB_AES
select CRYPTO_SKCIPHER
@@ -20,7 +20,7 @@ config CRYPTO_AES_RISCV64
config CRYPTO_CHACHA_RISCV64
tristate "Ciphers: ChaCha"
- depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ depends on 64BIT && PLATFORM_SUPPORTS_RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
select CRYPTO_SKCIPHER
select CRYPTO_LIB_CHACHA_GENERIC
help
@@ -31,7 +31,7 @@ config CRYPTO_CHACHA_RISCV64
config CRYPTO_GHASH_RISCV64
tristate "Hash functions: GHASH"
- depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ depends on 64BIT && PLATFORM_SUPPORTS_RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
select CRYPTO_GCM
help
GCM GHASH function (NIST SP 800-38D)
@@ -41,7 +41,7 @@ config CRYPTO_GHASH_RISCV64
config CRYPTO_SHA256_RISCV64
tristate "Hash functions: SHA-224 and SHA-256"
- depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ depends on 64BIT && PLATFORM_SUPPORTS_RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
select CRYPTO_SHA256
help
SHA-224 and SHA-256 secure hash algorithm (FIPS 180)
@@ -52,7 +52,7 @@ config CRYPTO_SHA256_RISCV64
config CRYPTO_SHA512_RISCV64
tristate "Hash functions: SHA-384 and SHA-512"
- depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ depends on 64BIT && PLATFORM_SUPPORTS_RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
select CRYPTO_SHA512
help
SHA-384 and SHA-512 secure hash algorithm (FIPS 180)
@@ -63,7 +63,7 @@ config CRYPTO_SHA512_RISCV64
config CRYPTO_SM3_RISCV64
tristate "Hash functions: SM3 (ShangMi 3)"
- depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ depends on 64BIT && PLATFORM_SUPPORTS_RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
select CRYPTO_HASH
select CRYPTO_SM3
help
@@ -75,7 +75,7 @@ config CRYPTO_SM3_RISCV64
config CRYPTO_SM4_RISCV64
tristate "Ciphers: SM4 (ShangMi 4)"
- depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ depends on 64BIT && PLATFORM_SUPPORTS_RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
select CRYPTO_ALGAPI
select CRYPTO_SM4
help
@@ -26,6 +26,9 @@
*/
static __must_check inline bool may_use_simd(void)
{
+ if (!has_vector())
+ return false;
+
/*
* RISCV_KERNEL_MODE_V is only set while preemption is disabled,
* and is clear whenever preemption is enabled.
@@ -37,7 +37,8 @@ static inline u32 riscv_v_flags(void)
static __always_inline bool has_vector(void)
{
- return riscv_has_extension_unlikely(RISCV_ISA_EXT_v);
+ return IS_ENABLED(CONFIG_PLATFORM_SUPPORTS_RISCV_ISA_V) ||
+ riscv_has_extension_likely(RISCV_ISA_EXT_v);
}
static inline void __riscv_v_vstate_clean(struct pt_regs *regs)
@@ -683,7 +683,6 @@ void __init riscv_fill_hwcap(void)
}
if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
- riscv_v_setup_vsize();
/*
* ISA string in device tree might have 'v' flag, but
* CONFIG_RISCV_ISA_V is disabled in kernel.
@@ -691,6 +690,8 @@ void __init riscv_fill_hwcap(void)
*/
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
+ else
+ riscv_v_setup_vsize();
}
memset(print_str, 0, sizeof(print_str));
@@ -428,17 +428,20 @@ SYM_CODE_START_LOCAL(reset_regs)
.Lreset_regs_done_fpu:
#endif /* CONFIG_FPU */
-#ifdef CONFIG_RISCV_ISA_V
+#if defined(CONFIG_PLATFORM_MAY_SUPPORT_RISCV_ISA_V)
csrr t0, CSR_MISA
li t1, COMPAT_HWCAP_ISA_V
and t0, t0, t1
beqz t0, .Lreset_regs_done_vector
-
+#endif
+#ifdef CONFIG_RISCV_ISA_V
/*
* Clear vector registers and reset vcsr
* VLMAX has a defined value, VLEN is a constant,
* and this form of vsetvli is defined to set vl to VLMAX.
*/
+ .option push
+ .option arch, +v
li t1, SR_VS
csrs CSR_STATUS, t1
csrs CSR_VCSR, x0
@@ -447,6 +450,7 @@ SYM_CODE_START_LOCAL(reset_regs)
vmv.v.i v8, 0
vmv.v.i v16, 0
vmv.v.i v24, 0
+ .option pop
/* note that the caller must clear SR_VS */
.Lreset_regs_done_vector:
#endif /* CONFIG_RISCV_ISA_V */
@@ -165,11 +165,13 @@ void flush_thread(void)
#endif
#ifdef CONFIG_RISCV_ISA_V
/* Reset vector state */
- riscv_v_vstate_ctrl_init(current);
- riscv_v_vstate_off(task_pt_regs(current));
- kfree(current->thread.vstate.datap);
- memset(¤t->thread.vstate, 0, sizeof(struct __riscv_v_ext_state));
- clear_tsk_thread_flag(current, TIF_RISCV_V_DEFER_RESTORE);
+ if (has_vector()) {
+ riscv_v_vstate_ctrl_init(current);
+ riscv_v_vstate_off(task_pt_regs(current));
+ kfree(current->thread.vstate.datap);
+ memset(¤t->thread.vstate, 0, sizeof(struct __riscv_v_ext_state));
+ clear_tsk_thread_flag(current, TIF_RISCV_V_DEFER_RESTORE);
+ }
#endif
}
@@ -92,6 +92,9 @@ static int riscv_vr_get(struct task_struct *target,
struct __riscv_v_ext_state *vstate = &target->thread.vstate;
struct __riscv_v_regset_state ptrace_vstate;
+ if (!has_vector())
+ return 0;
+
if (!riscv_v_vstate_query(task_pt_regs(target)))
return -EINVAL;
@@ -127,6 +130,9 @@ static int riscv_vr_set(struct task_struct *target,
struct __riscv_v_ext_state *vstate = &target->thread.vstate;
struct __riscv_v_regset_state ptrace_vstate;
+ if (!has_vector())
+ return 0;
+
if (!riscv_v_vstate_query(task_pt_regs(target)))
return -EINVAL;
@@ -21,7 +21,6 @@ asmlinkage int enter_vector_usercopy(void *dst, void *src, size_t n)
{
size_t remain, copied;
- /* skip has_vector() check because it has been done by the asm */
if (!may_use_simd())
goto fallback;
@@ -5,6 +5,8 @@
#include <asm/asm-extable.h>
#include <asm/csr.h>
+.option arch, +v
+
#define pDst a0
#define pSrc a1
#define iNum a2
@@ -6,6 +6,8 @@
#include <linux/export.h>
#include <asm/asm.h>
+.option arch, +v
+
SYM_FUNC_START(xor_regs_2_)
vsetvli a3, a0, e8, m8, ta, ma
vle8.v v0, (a1)
Current versions of the kernel add "v" to the march and then immeidately filter it out such that "v" is not passed to CFLAGS. Instead of doing this filtering, code blocks in the kernel that want to use vector assembly have been changed to locally enable vector (using ".option arch, +v"). To support kernels that can run on hardware that may support vector, the config option PLATFORM_MAY_SUPPORT_RISCV_ISA_V is added, and the previous behavior of RISCV_ISA_V is retained with the option CONFIG_PLATFORM_SUPPORTS_RISCV_ISA_V. When the hardware is assumed to support vector, has_vector() unconditionally returns true. "v" is not added to the toolchain march even when the hardware is assumed to support vector because kernel vector code must be guarded by kernel_vector_begin/end. Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> --- arch/riscv/Kconfig | 54 ------------------------- arch/riscv/Kconfig.isa | 85 ++++++++++++++++++++++++++++++++++++++++ arch/riscv/Makefile | 6 +-- arch/riscv/crypto/Kconfig | 14 +++---- arch/riscv/include/asm/simd.h | 3 ++ arch/riscv/include/asm/vector.h | 3 +- arch/riscv/kernel/cpufeature.c | 3 +- arch/riscv/kernel/head.S | 8 +++- arch/riscv/kernel/process.c | 12 +++--- arch/riscv/kernel/ptrace.c | 6 +++ arch/riscv/lib/riscv_v_helpers.c | 1 - arch/riscv/lib/uaccess_vector.S | 2 + arch/riscv/lib/xor.S | 2 + 13 files changed, 123 insertions(+), 76 deletions(-)