Message ID | 20230629142228.1125715-1-bjorn@kernel.org (mailing list archive) |
---|---|
State | Accepted |
Commit | 9657e9b7d2538dc73c24947aa00a8525dfb8062c |
Headers | show |
Series | [v4] riscv: Discard vector state on syscalls | expand |
Context | Check | Description |
---|---|---|
conchuod/cover_letter | success | Single patches do not need cover letters |
conchuod/tree_selection | success | Guessed tree name to be for-next at HEAD 488833ccdcac |
conchuod/fixes_present | success | Fixes tag not required for -next series |
conchuod/maintainers_pattern | success | MAINTAINERS pattern errors before the patch: 6 and now 6 |
conchuod/verify_signedoff | success | Signed-off-by tag matches author and committer |
conchuod/kdoc | success | Errors and warnings before: 0 this patch: 0 |
conchuod/build_rv64_clang_allmodconfig | success | Errors and warnings before: 12 this patch: 12 |
conchuod/module_param | success | Was 0 now: 0 |
conchuod/build_rv64_gcc_allmodconfig | success | Errors and warnings before: 120 this patch: 120 |
conchuod/build_rv32_defconfig | success | Build OK |
conchuod/dtb_warn_rv64 | success | Errors and warnings before: 20 this patch: 20 |
conchuod/header_inline | success | No static functions without inline keyword in header files |
conchuod/checkpatch | warning | CHECK: Lines should not end with a '(' |
conchuod/build_rv64_nommu_k210_defconfig | success | Build OK |
conchuod/verify_fixes | success | No Fixes tag |
conchuod/build_rv64_nommu_virt_defconfig | success | Build OK |
On Thu, Jun 29, 2023 at 10:22 PM Björn Töpel <bjorn@kernel.org> wrote: > > From: Björn Töpel <bjorn@rivosinc.com> > > The RISC-V vector specification states: > Executing a system call causes all caller-saved vector registers > (v0-v31, vl, vtype) and vstart to become unspecified. > > The vector registers are set to all 1s, vill is set (invalid), and the > vector status is set to Dirty. > > That way we can prevent userspace from accidentally relying on the > stated save. > > Rémi pointed out [1] that writing to the registers might be > superfluous, and setting vill is sufficient. > > Link: https://lore.kernel.org/linux-riscv/12784326.9UPPK3MAeB@basile.remlab.net/ # [1] > Suggested-by: Darius Rad <darius@bluespec.com> > Suggested-by: Palmer Dabbelt <palmer@rivosinc.com> > Suggested-by: Rémi Denis-Courmont <remi@remlab.net> > Signed-off-by: Björn Töpel <bjorn@rivosinc.com> Thanks, Reviewed-by: Andy Chiu <andy.chiu@sifive.com>
On Thu, 29 Jun 2023 16:22:28 +0200, Björn Töpel wrote: > The RISC-V vector specification states: > Executing a system call causes all caller-saved vector registers > (v0-v31, vl, vtype) and vstart to become unspecified. > > The vector registers are set to all 1s, vill is set (invalid), and the > vector status is set to Dirty. > > [...] Applied, thanks! [1/1] riscv: Discard vector state on syscalls https://git.kernel.org/palmer/c/9657e9b7d253 Best regards,
Hello: This patch was applied to riscv/linux.git (for-next) by Palmer Dabbelt <palmer@rivosinc.com>: On Thu, 29 Jun 2023 16:22:28 +0200 you wrote: > From: Björn Töpel <bjorn@rivosinc.com> > > The RISC-V vector specification states: > Executing a system call causes all caller-saved vector registers > (v0-v31, vl, vtype) and vstart to become unspecified. > > The vector registers are set to all 1s, vill is set (invalid), and the > vector status is set to Dirty. > > [...] Here is the summary with links: - [v4] riscv: Discard vector state on syscalls https://git.kernel.org/riscv/c/9657e9b7d253 You are awesome, thank you!
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h index 04c0b07bf6cd..3d78930cab51 100644 --- a/arch/riscv/include/asm/vector.h +++ b/arch/riscv/include/asm/vector.h @@ -33,6 +33,11 @@ static inline void __riscv_v_vstate_clean(struct pt_regs *regs) regs->status = (regs->status & ~SR_VS) | SR_VS_CLEAN; } +static inline void __riscv_v_vstate_dirty(struct pt_regs *regs) +{ + regs->status = (regs->status & ~SR_VS) | SR_VS_DIRTY; +} + static inline void riscv_v_vstate_off(struct pt_regs *regs) { regs->status = (regs->status & ~SR_VS) | SR_VS_OFF; @@ -128,6 +133,34 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_ riscv_v_disable(); } +static inline void __riscv_v_vstate_discard(void) +{ + unsigned long vl, vtype_inval = 1UL << (BITS_PER_LONG - 1); + + riscv_v_enable(); + asm volatile ( + ".option push\n\t" + ".option arch, +v\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" + "vmv.v.i v16, -1\n\t" + "vmv.v.i v24, -1\n\t" + "vsetvl %0, x0, %1\n\t" + ".option pop\n\t" + : "=&r" (vl) : "r" (vtype_inval) : "memory"); + riscv_v_disable(); +} + +static inline void riscv_v_vstate_discard(struct pt_regs *regs) +{ + if ((regs->status & SR_VS) == SR_VS_OFF) + return; + + __riscv_v_vstate_discard(); + __riscv_v_vstate_dirty(regs); +} + static inline void riscv_v_vstate_save(struct task_struct *task, struct pt_regs *regs) { @@ -173,6 +206,7 @@ static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return fals static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; } static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; } #define riscv_v_vsize (0) +#define riscv_v_vstate_discard(regs) do {} while (0) #define riscv_v_vstate_save(task, regs) do {} while (0) #define riscv_v_vstate_restore(task, regs) do {} while (0) #define __switch_to_vector(__prev, __next) do {} while (0) diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 5158961ea977..5ff63a784a6d 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -296,6 +296,8 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) regs->epc += 4; regs->orig_a0 = regs->a0; + riscv_v_vstate_discard(regs); + syscall = syscall_enter_from_user_mode(regs, syscall); if (syscall < NR_syscalls)