Re: [PATCH v5 1/9] riscv: ptrace: return ENODATA for inactive vector extension

Andy Chiu
2026-01-07T06:48:58Z

On Sun, Dec 14, 2025 at 10:35 AM Sergey Matyukevich <geomatsi@gmail.com> wrote:
>
> From: Ilya Mamay <mmamayka01@gmail.com>
>
> Currently, ptrace returns EINVAL when the vector extension is supported
> but not yet activated for the traced process. This error code is not
> always appropriate since the ptrace arguments may be valid.
>
> Debug tools like gdbserver expect ENODATA when the requested register
> set is not active, e.g. see [1]. This expectation seems to be more
> appropriate, so modify the vector ptrace implementation to return:
> - EINVAL when V extension is not supported
> - ENODATA when V extension is supported but not active
>
> [1] https://github.com/bminor/binutils-gdb/blob/637f25e88675fa47e47f9cc5e2cf37384836b8a2/gdbserver/linux-low.cc#L5020
>
> Signed-off-by: Ilya Mamay <mmamayka01@gmail.com>
> Signed-off-by: Sergey Matyukevich <geomatsi@gmail.com>

Reviewed-by: Andy Chiu <andybnac@gmail.com>

> ---
> arch/riscv/kernel/ptrace.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
> index e6272d74572f..9d203fb84f5e 100644
> --- a/arch/riscv/kernel/ptrace.c
> +++ b/arch/riscv/kernel/ptrace.c
> @@ -95,9 +95,12 @@ static int riscv_vr_get(struct task_struct *target,
> struct __riscv_v_ext_state *vstate = &target->thread.vstate;
> struct __riscv_v_regset_state ptrace_vstate;
>
> - if (!riscv_v_vstate_query(task_pt_regs(target)))
> + if (!(has_vector() || has_xtheadvector()))
> return -EINVAL;
>
> + if (!riscv_v_vstate_query(task_pt_regs(target)))
> + return -ENODATA;
> +
> /*
> * Ensure the vector registers have been saved to the memory before
> * copying them to membuf.
> @@ -130,9 +133,12 @@ static int riscv_vr_set(struct task_struct *target,
> struct __riscv_v_ext_state *vstate = &target->thread.vstate;
> struct __riscv_v_regset_state ptrace_vstate;
>
> - if (!riscv_v_vstate_query(task_pt_regs(target)))
> + if (!(has_vector() || has_xtheadvector()))
> return -EINVAL;
>
> + if (!riscv_v_vstate_query(task_pt_regs(target)))
> + return -ENODATA;
> +
> /* Copy rest of the vstate except datap */
> ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ptrace_vstate, 0,
> sizeof(struct __riscv_v_regset_state));
> --
> 2.52.0
>