summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Mamay <mmamayka01@gmail.com>2026-01-25 21:09:56 -0700
committerPaul Walmsley <pjw@kernel.org>2026-01-29 02:38:40 -0700
commit8cdb04bd06c167461b357150b3ca46983eb70dc3 (patch)
tree152bf11ca966d8c7df95e0699f11e3575f1e2764
parentd30c1683aaecb93d2ab95685dc4300a33d3cea7a (diff)
riscv: ptrace: return ENODATA for inactive vector extension
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> Tested-by: Andy Chiu <andybnac@gmail.com> Link: https://patch.msgid.link/20251214163537.1054292-2-geomatsi@gmail.com Signed-off-by: Paul Walmsley <pjw@kernel.org>
-rw-r--r--arch/riscv/kernel/ptrace.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 57e257d459e8..97636fdfeb77 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -99,9 +99,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.
@@ -134,9 +137,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));