From: Gleb Pesin 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@vger.kernel.org Assisted-by: LLM Signed-off-by: Gleb Pesin --- 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 #include #include +#include +#include #include .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