On Sun, Dec 14, 2025 at 10:35 AM Sergey Matyukevich <[email protected]> wrote: > > The vstate in thread_struct is zeroed when the vector context is > initialized. That includes read-only register vlenb, which holds > the vector register length in bytes. Zeroed state persists until > mstatus.VS becomes 'dirty' and a context switch saves the actual > hardware values. > > This can expose the zero vlenb value to the user-space in early > debug scenarios, e.g. when ptrace attaches to a traced process > early, before any vector instruction except the first one was > executed. > > Fix this by specifying proper vlenb on vector context init. > > Signed-off-by: Sergey Matyukevich <[email protected]>
Reviewed-by: Andy Chiu <[email protected]> > --- > arch/riscv/kernel/vector.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c > index 3ed071dab9d8..b112166d51e9 100644 > --- a/arch/riscv/kernel/vector.c > +++ b/arch/riscv/kernel/vector.c > @@ -111,8 +111,8 @@ bool insn_is_vector(u32 insn_buf) > return false; > } > > -static int riscv_v_thread_zalloc(struct kmem_cache *cache, > - struct __riscv_v_ext_state *ctx) > +static int riscv_v_thread_ctx_alloc(struct kmem_cache *cache, > + struct __riscv_v_ext_state *ctx) > { > void *datap; > > @@ -122,13 +122,15 @@ static int riscv_v_thread_zalloc(struct kmem_cache > *cache, > > ctx->datap = datap; > memset(ctx, 0, offsetof(struct __riscv_v_ext_state, datap)); > + ctx->vlenb = riscv_v_vsize / 32; > + > return 0; > } > > void riscv_v_thread_alloc(struct task_struct *tsk) > { > #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE > - riscv_v_thread_zalloc(riscv_v_kernel_cachep, > &tsk->thread.kernel_vstate); > + riscv_v_thread_ctx_alloc(riscv_v_kernel_cachep, > &tsk->thread.kernel_vstate); > #endif > } > > @@ -214,12 +216,14 @@ bool riscv_v_first_use_handler(struct pt_regs *regs) > * context where VS has been off. So, try to allocate the user's V > * context and resume execution. > */ > - if (riscv_v_thread_zalloc(riscv_v_user_cachep, > ¤t->thread.vstate)) { > + if (riscv_v_thread_ctx_alloc(riscv_v_user_cachep, > ¤t->thread.vstate)) { > force_sig(SIGBUS); > return true; > } > + > riscv_v_vstate_on(regs); > riscv_v_vstate_set_restore(current, regs); > + > return true; > } > > -- > 2.52.0 >

