diff options
author | Björn Töpel <bjorn@rivosinc.com> | 2023-06-29 16:22:28 +0200 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2023-07-04 08:59:24 -0700 |
commit | 9657e9b7d2538dc73c24947aa00a8525dfb8062c (patch) | |
tree | ad3a5963a5c578d99824bdc127f176004d6b7eda /arch/riscv/kernel/traps.c | |
parent | 85fadc0d04119c2fe4a20287767ab904c6d21ba1 (diff) |
riscv: Discard vector state on syscalls
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>
Link: https://lore.kernel.org/r/20230629142228.1125715-1-bjorn@kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'arch/riscv/kernel/traps.c')
-rw-r--r-- | arch/riscv/kernel/traps.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index bc02b282a403..f910dfccbf5d 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -302,6 +302,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) |