[PATCH] riscv: Discard vector state on syscalls
Palmer Dabbelt
palmer at dabbelt.com
Thu Jun 22 11:02:08 PDT 2023
On Thu, 22 Jun 2023 10:55:54 PDT (-0700), Darius Rad wrote:
> On Thu, Jun 22, 2023 at 10:46:31AM -0700, Palmer Dabbelt wrote:
>> On Thu, 22 Jun 2023 10:36:13 PDT (-0700), bjorn at kernel.org wrote:
>> > From: Björn Töpel <bjorn at 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 cleared, vill is set (invalid), and the
>> > vector status is set to Initial.
>> >
>> > That way we can prevent userspace from accidentally relying on the
>> > stated save.
>> >
>> > Rémi pointed out [1] that clearing 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: Palmer Dabbelt <palmer at rivosinc.com>
>> > Suggested-by: Rémi Denis-Courmont <remi at remlab.net>
>> > Signed-off-by: Björn Töpel <bjorn at rivosinc.com>
>> > ---
>> >
>> > I figured I'd sent out a proper patch. I like Andy's optimization
>> > patch, but TBH I think we should do that as a follow up.
>> >
>> > As Rémi pointed out, the clearing might be opted out, but I left it in
>> > here.
>>
>> I think we're going to end up with a bunch of uarch-specific stuff here, but
>> for now having the heavy hammer seems safest. There's no V hardware yet so
>> we can't really tell how anything performs, at least this way we're
>> definately not leaking anything.
>>
>> So I'm OK with this. I'd also be fine with clearing to all-1s, I think it's
>> kind of splitting hairs at this point: the 1s are nice because they're what
>> the rest of V does, but setting vill should make everything trap anyway so
>> maybe it doesn't matter -- and it's not clear if 1 or 0 will allow initial,
>> so who knows.
>>
>> Darius: I'm cool swapping over to the 1s if you feel strongly about it.
>> Bjorn says Sweeden is on vacation, so just LMK and I'll re-spin it with the
>> 1s.
>
> I think all 1s would be preferred, but I don't think it's particularly
> critical (splitting hairs, like you said), so I'll let you make the call.
OK, I'm just going to take this then as it's the less work option ;)
>
>>
>> Regardless I'd like to pick up something that blows away V state for this
>> merge window, as it'll make sure the uABI is quite strictly enforced.
>>
>> > Björn
>> >
>> > ---
>> > arch/riscv/include/asm/vector.h | 25 +++++++++++++++++++++++++
>> > arch/riscv/kernel/traps.c | 2 ++
>> > 2 files changed, 27 insertions(+)
>> >
>> > diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
>> > index 04c0b07bf6cd..692ce55e4a69 100644
>> > --- a/arch/riscv/include/asm/vector.h
>> > +++ b/arch/riscv/include/asm/vector.h
>> > @@ -163,6 +163,30 @@ static inline void __switch_to_vector(struct task_struct *prev,
>> > void riscv_v_vstate_ctrl_init(struct task_struct *tsk);
>> > bool riscv_v_vstate_ctrl_user_allowed(void);
>> >
>> > +static inline void riscv_v_vstate_discard(struct pt_regs *regs)
>> > +{
>> > + unsigned long vl, vtype_inval = 1UL << (BITS_PER_LONG - 1);
>> > +
>> > + if (!riscv_v_vstate_query(regs))
>> > + return;
>> > +
>> > + 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, 0\n\t"
>> > + "vmv.v.i v8, 0\n\t"
>> > + "vmv.v.i v16, 0\n\t"
>> > + "vmv.v.i v24, 0\n\t"
>> > + "vsetvl %0, x0, %1\n\t"
>> > + ".option pop\n\t"
>> > + : "=&r" (vl) : "r" (vtype_inval) : "memory");
>> > + riscv_v_disable();
>> > +
>> > + riscv_v_vstate_on(regs);
>> > +}
>> > +
>> > #else /* ! CONFIG_RISCV_ISA_V */
>> >
>> > struct pt_regs;
>> > @@ -178,6 +202,7 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
>> > #define __switch_to_vector(__prev, __next) do {} while (0)
>> > #define riscv_v_vstate_off(regs) do {} while (0)
>> > #define riscv_v_vstate_on(regs) do {} while (0)
>> > +#define riscv_v_vstate_discard(regs) do {} while (0)
>> >
>> > #endif /* CONFIG_RISCV_ISA_V */
>> >
>> > diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
>> > index 05ffdcd1424e..00c68b57ff88 100644
>> > --- a/arch/riscv/kernel/traps.c
>> > +++ b/arch/riscv/kernel/traps.c
>> > @@ -295,6 +295,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)
>> >
>> > base-commit: 4681dacadeefa5ca6017e00736adc1d7dc963c6a
>
> --
> You received this message because you are subscribed to the Google Groups "linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux+unsubscribe at rivosinc.com.
> To view this discussion on the web visit https://groups.google.com/a/rivosinc.com/d/msgid/linux/ZJSLKrB/4xaYB75d%40bruce.bluespec.com.
> For more options, visit https://groups.google.com/a/rivosinc.com/d/optout.
More information about the linux-riscv
mailing list