diff mbox series

[v2,2/8] riscv: Add PLATFORM_MAY_SUPPORT_RISCV_ISA_V Kconfig option

Message ID 20240507-compile_kernel_with_extensions-v2-2-722c21c328c6@rivosinc.com (mailing list archive)
State Changes Requested
Headers show
Series riscv: Support compiling the kernel with more extensions | expand

Checks

Context Check Description
conchuod/vmtest-fixes-PR fail merge-conflict

Commit Message

Charlie Jenkins May 8, 2024, 1:36 a.m. UTC
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(-)

Comments

Conor Dooley May 10, 2024, 8:43 p.m. UTC | #1
Hey Charlie,

On Tue, May 07, 2024 at 06:36:28PM -0700, Charlie Jenkins wrote:
> 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").

Other content in the series aside, since this is a change that could be
made independently of the main series objectives, I figured it was worth
pointing out that this is not a change without downsides: I think that
it would drop support for vector with most versions of LLVM as
.option arch support there is much more recent thing than it is for gcc.
Off the top of my head I don't know exactly the versions involved, but
it is something like LLVM-14 supports vector but only LLVM-17 and later
supports .option arch.

Thanks,
Conor.
Charlie Jenkins May 10, 2024, 9:43 p.m. UTC | #2
On Fri, May 10, 2024 at 09:43:33PM +0100, Conor Dooley wrote:
> Hey Charlie,
> 
> On Tue, May 07, 2024 at 06:36:28PM -0700, Charlie Jenkins wrote:
> > 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").
> 
> Other content in the series aside, since this is a change that could be
> made independently of the main series objectives, I figured it was worth
> pointing out that this is not a change without downsides: I think that
> it would drop support for vector with most versions of LLVM as
> .option arch support there is much more recent thing than it is for gcc.
> Off the top of my head I don't know exactly the versions involved, but
> it is something like LLVM-14 supports vector but only LLVM-17 and later
> supports .option arch.

Toolchain incompatibilities are always fun. It does look like .option
arch was introduced in LLVM-17. That would be a regression. We do use
.option arch for every other extension, but vector was treated special
when it was introduced unfortunately so maybe we have to live with the
weird march parsing hack.

- Charlie

> 
> Thanks,
> Conor.
Conor Dooley May 10, 2024, 10:26 p.m. UTC | #3
On Fri, May 10, 2024 at 02:43:10PM -0700, Charlie Jenkins wrote:
> On Fri, May 10, 2024 at 09:43:33PM +0100, Conor Dooley wrote:
> > Hey Charlie,
> > 
> > On Tue, May 07, 2024 at 06:36:28PM -0700, Charlie Jenkins wrote:
> > > 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").
> > 
> > Other content in the series aside, since this is a change that could be
> > made independently of the main series objectives, I figured it was worth
> > pointing out that this is not a change without downsides: I think that
> > it would drop support for vector with most versions of LLVM as
> > .option arch support there is much more recent thing than it is for gcc.
> > Off the top of my head I don't know exactly the versions involved, but
> > it is something like LLVM-14 supports vector but only LLVM-17 and later
> > supports .option arch.
> 
> Toolchain incompatibilities are always fun. It does look like .option
> arch was introduced in LLVM-17. That would be a regression. We do use
> .option arch for every other extension, but vector was treated special
> when it was introduced unfortunately so maybe we have to live with the
> weird march parsing hack.

I wrote out a long message about the history of some of this, but right
at the end I was scrolling through my chat logs with Andy and realised
we actually did make it depend on AS_HAS_OPTION_ARCH, so it should be
safe to do without regressing anything. I didn't notice in the diff that
the AS_HAS_OPTION_ARCH was a movement, not an addition. Maybe Andy knows
why, despite the dependency on the assembler having it, we didn't use it
everywhere.
Conor Dooley May 15, 2024, 2:34 p.m. UTC | #4
On Fri, May 10, 2024 at 11:26:22PM +0100, Conor Dooley wrote:
> On Fri, May 10, 2024 at 02:43:10PM -0700, Charlie Jenkins wrote:
> > On Fri, May 10, 2024 at 09:43:33PM +0100, Conor Dooley wrote:
> > > Hey Charlie,
> > > 
> > > On Tue, May 07, 2024 at 06:36:28PM -0700, Charlie Jenkins wrote:
> > > > 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").
> > > 
> > > Other content in the series aside, since this is a change that could be
> > > made independently of the main series objectives, I figured it was worth
> > > pointing out that this is not a change without downsides: I think that
> > > it would drop support for vector with most versions of LLVM as
> > > .option arch support there is much more recent thing than it is for gcc.
> > > Off the top of my head I don't know exactly the versions involved, but
> > > it is something like LLVM-14 supports vector but only LLVM-17 and later
> > > supports .option arch.
> > 
> > Toolchain incompatibilities are always fun. It does look like .option
> > arch was introduced in LLVM-17. That would be a regression. We do use
> > .option arch for every other extension, but vector was treated special
> > when it was introduced unfortunately so maybe we have to live with the
> > weird march parsing hack.
> 
> I wrote out a long message about the history of some of this, but right
> at the end I was scrolling through my chat logs with Andy and realised
> we actually did make it depend on AS_HAS_OPTION_ARCH, so it should be
> safe to do without regressing anything. I didn't notice in the diff that
> the AS_HAS_OPTION_ARCH was a movement, not an addition. Maybe Andy knows
> why, despite the dependency on the assembler having it, we didn't use it
> everywhere.

And while I remember, the bits of this doing the .option arch conversion
should be (IMO) split into a different patch to anything dealing with
Kconfig options etc.

Cheers,
Conor.
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index c2a4f5364707..c2e9eded0a7d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -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
diff --git a/arch/riscv/Kconfig.isa b/arch/riscv/Kconfig.isa
index 08b7af5aabb0..0663c98b5b17 100644
--- a/arch/riscv/Kconfig.isa
+++ b/arch/riscv/Kconfig.isa
@@ -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.
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index e1be36004097..e1111e62ca20 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -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
diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig
index ad58dad9a580..5f7ea675a8cf 100644
--- a/arch/riscv/crypto/Kconfig
+++ b/arch/riscv/crypto/Kconfig
@@ -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
diff --git a/arch/riscv/include/asm/simd.h b/arch/riscv/include/asm/simd.h
index adb50f3ec205..81508325fd51 100644
--- a/arch/riscv/include/asm/simd.h
+++ b/arch/riscv/include/asm/simd.h
@@ -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.
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index 731dcd0ed4de..a08c4bf92ecd 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -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)
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 3ed2359eae35..7cb365714855 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -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));
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 4236a69c35cb..b027be82bbb3 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -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 */
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index e4bc61c4e58a..3ba7bf63ccb2 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -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(&current->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(&current->thread.vstate, 0, sizeof(struct __riscv_v_ext_state));
+		clear_tsk_thread_flag(current, TIF_RISCV_V_DEFER_RESTORE);
+	}
 #endif
 }
 
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 92731ff8c79a..bdfaed2a4023 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -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;
 
diff --git a/arch/riscv/lib/riscv_v_helpers.c b/arch/riscv/lib/riscv_v_helpers.c
index be38a93cedae..661c77fdd7f7 100644
--- a/arch/riscv/lib/riscv_v_helpers.c
+++ b/arch/riscv/lib/riscv_v_helpers.c
@@ -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;
 
diff --git a/arch/riscv/lib/uaccess_vector.S b/arch/riscv/lib/uaccess_vector.S
index 7c45f26de4f7..4de37a3a2163 100644
--- a/arch/riscv/lib/uaccess_vector.S
+++ b/arch/riscv/lib/uaccess_vector.S
@@ -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
diff --git a/arch/riscv/lib/xor.S b/arch/riscv/lib/xor.S
index b28f2430e52f..9a3e2c19efc9 100644
--- a/arch/riscv/lib/xor.S
+++ b/arch/riscv/lib/xor.S
@@ -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)