[PATCH 3/3] riscv: Disable the xtheadvector unit on kernel entry

From: Gleb Pesin via B4 Relay

Date: Mon Oct 05 2026 - 20:36:46 EST


From: Gleb Pesin <dormancygrace@xxxxxxxxx>

handle_exception clears SR_FS_VS on entry so that stray floating-point
or vector instructions in the kernel raise an illegal-instruction
exception. xtheadvector keeps its vector status in SR_VS_THEAD
(sstatus bits 24:23), which that mask does not cover. On 64-bit kernels
bit 23 happens to be cleared as SR_SPELP, so the T-Head field is only
partly reset: DIRTY becomes CLEAN, and the vector unit stays enabled in
the kernel after a trap from a context that used it.

Clear the whole SR_VS_THEAD field on cores with xtheadvector. The status
saved in pt_regs still holds the interrupted value, so the vector state
is restored on return exactly as before. Other cores keep the current
mask, because bit 24 is not part of the vector status there.

Fixes: d863910eabaf ("riscv: vector: Support xtheadvector save/restore")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Gleb Pesin <dormancygrace@xxxxxxxxx>
---
arch/riscv/kernel/entry.S | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index d799c4e56..aeb99c20b 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -16,6 +16,8 @@
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm/errata_list.h>
+#include <asm/vendor_extensions.h>
+#include <asm/vendor_extensions/thead.h>
#include <linux/sizes.h>

.section .irqentry.text, "ax"
@@ -176,9 +178,14 @@ SYM_CODE_START(handle_exception)
* actual user copy routines.
*
* Disable the FPU/Vector to detect illegal usage of floating point
- * or vector in kernel space.
+ * or vector in kernel space. xtheadvector keeps its vector status in
+ * a different sstatus field; those bits are reserved elsewhere.
*/
- li t0, SR_SUM | SR_FS_VS
+ ALTERNATIVE(__stringify(li t0, SR_SUM | SR_FS_VS),
+ __stringify(li t0, SR_SUM | SR_FS_VS | SR_VS_THEAD),
+ THEAD_VENDOR_ID,
+ RISCV_VENDOR_EXT_ALTERNATIVES_BASE + RISCV_ISA_VENDOR_EXT_XTHEADVECTOR,
+ CONFIG_RISCV_ISA_XTHEADVECTOR)
#ifdef CONFIG_64BIT
li t1, SR_ELP
or t0, t0, t1

--
2.53.0