From: Sergey Matyukevich <geomatsi@gmail.com>
To: linux-riscv@lists.infradead.org, linux-kselftest@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, "Paul Walmsley" <pjw@kernel.org>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
"Alexandre Ghiti" <alex@ghiti.fr>,
"Oleg Nesterov" <oleg@redhat.com>,
"Shuah Khan" <shuah@kernel.org>,
"Jisheng Zhang" <jszhang@kernel.org>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Thomas Huth" <thuth@redhat.com>,
"Charlie Jenkins" <charlie@rivosinc.com>,
"Andy Chiu" <andybnac@gmail.com>,
"Han Gao" <rabenda.cn@gmail.com>,
"Samuel Holland" <samuel.holland@sifive.com>,
"Nam Cao" <namcao@linutronix.de>,
"Joel Granados" <joel.granados@kernel.org>,
"Clément Léger" <cleger@rivosinc.com>,
"Conor Dooley" <conor.dooley@microchip.com>,
"Sergey Matyukevich" <geomatsi@gmail.com>
Subject: [PATCH v2 4/6] riscv: vector: allow to force vector context save
Date: Tue, 7 Oct 2025 14:58:20 +0300 [thread overview]
Message-ID: <20251007115840.2320557-5-geomatsi@gmail.com> (raw)
In-Reply-To: <20251007115840.2320557-1-geomatsi@gmail.com>
When ptrace updates vector CSR registers for a traced process, the
changes may not be immediately visible to the next ptrace operations
due to vector context switch optimizations.
The function 'riscv_v_vstate_save' saves context only if mstatus.VS is
'dirty'. However mstatus.VS of the traced process context may remain
'clean' between two breakpoints, if no vector instructions were executed
between those two breakpoints. In this case the vector context will not
be saved at the second breakpoint. As a result, the second ptrace may
read stale vector CSR values.
Fix this by introducing a TIF flag that forces vector context save on
the next context switch, regardless of mstatus.VS state. Set this
flag on ptrace oprations that modify vector CSR registers.
Signed-off-by: Sergey Matyukevich <geomatsi@gmail.com>
---
arch/riscv/include/asm/thread_info.h | 2 ++
arch/riscv/include/asm/vector.h | 3 +++
arch/riscv/kernel/process.c | 2 ++
arch/riscv/kernel/ptrace.c | 5 +++++
4 files changed, 12 insertions(+)
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 836d80dd2921..e05e9aa89c43 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -118,7 +118,9 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
#define TIF_32BIT 16 /* compat-mode 32bit process */
#define TIF_RISCV_V_DEFER_RESTORE 17 /* restore Vector before returing to user */
+#define TIF_RISCV_V_FORCE_SAVE 13 /* force Vector context save */
#define _TIF_RISCV_V_DEFER_RESTORE BIT(TIF_RISCV_V_DEFER_RESTORE)
+#define _TIF_RISCV_V_FORCE_SAVE BIT(TIF_RISCV_V_FORCE_SAVE)
#endif /* _ASM_RISCV_THREAD_INFO_H */
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index b61786d43c20..d3770e13da93 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -370,6 +370,9 @@ static inline void __switch_to_vector(struct task_struct *prev,
{
struct pt_regs *regs;
+ if (test_and_clear_tsk_thread_flag(prev, TIF_RISCV_V_FORCE_SAVE))
+ __riscv_v_vstate_dirty(task_pt_regs(prev));
+
if (riscv_preempt_v_started(prev)) {
if (riscv_v_is_on()) {
WARN_ON(prev->thread.riscv_v_flags & RISCV_V_CTX_DEPTH_MASK);
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 31a392993cb4..47959c55cefb 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -183,6 +183,7 @@ void flush_thread(void)
kfree(current->thread.vstate.datap);
memset(¤t->thread.vstate, 0, sizeof(struct __riscv_v_ext_state));
clear_tsk_thread_flag(current, TIF_RISCV_V_DEFER_RESTORE);
+ clear_tsk_thread_flag(current, TIF_RISCV_V_FORCE_SAVE);
#endif
#ifdef CONFIG_RISCV_ISA_SUPM
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SUPM))
@@ -205,6 +206,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
memset(&dst->thread.vstate, 0, sizeof(struct __riscv_v_ext_state));
memset(&dst->thread.kernel_vstate, 0, sizeof(struct __riscv_v_ext_state));
clear_tsk_thread_flag(dst, TIF_RISCV_V_DEFER_RESTORE);
+ clear_tsk_thread_flag(dst, TIF_RISCV_V_FORCE_SAVE);
return 0;
}
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 906cf1197edc..569f756bef23 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -148,6 +148,11 @@ static int riscv_vr_set(struct task_struct *target,
if (vstate->vlenb != ptrace_vstate.vlenb)
return -EINVAL;
+ if (vstate->vtype != ptrace_vstate.vtype ||
+ vstate->vcsr != ptrace_vstate.vcsr ||
+ vstate->vl != ptrace_vstate.vl)
+ set_tsk_thread_flag(target, TIF_RISCV_V_FORCE_SAVE);
+
vstate->vstart = ptrace_vstate.vstart;
vstate->vl = ptrace_vstate.vl;
vstate->vtype = ptrace_vstate.vtype;
--
2.51.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2025-10-07 11:59 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-07 11:58 [PATCH v2 0/6] riscv: vector: misc ptrace fixes for debug use-cases Sergey Matyukevich
2025-10-07 11:58 ` [PATCH v2 1/6] selftests: riscv: test ptrace vector interface Sergey Matyukevich
2025-10-07 11:58 ` [PATCH v2 2/6] riscv: ptrace: return ENODATA for inactive vector extension Sergey Matyukevich
2025-10-07 11:58 ` [PATCH v2 3/6] selftests: riscv: set invalid vtype using ptrace Sergey Matyukevich
2025-10-07 11:58 ` Sergey Matyukevich [this message]
2025-10-15 20:18 ` [PATCH v2 4/6] riscv: vector: allow to force vector context save Andy Chiu
2025-10-15 21:32 ` Andy Chiu
2025-10-19 21:29 ` Sergey Matyukevich
2025-10-21 21:53 ` Andy Chiu
2025-10-07 11:58 ` [PATCH v2 5/6] selftests: riscv: verify initial vector state with ptrace Sergey Matyukevich
2025-10-07 11:58 ` [PATCH v2 6/6] riscv: vector: initialize vlenb on the first context switch Sergey Matyukevich
2025-10-15 19:54 ` Andy Chiu
2025-10-19 21:43 ` Sergey Matyukevich
2025-10-21 22:07 ` Andy Chiu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251007115840.2320557-5-geomatsi@gmail.com \
--to=geomatsi@gmail.com \
--cc=alex@ghiti.fr \
--cc=andybnac@gmail.com \
--cc=aou@eecs.berkeley.edu \
--cc=charlie@rivosinc.com \
--cc=cleger@rivosinc.com \
--cc=conor.dooley@microchip.com \
--cc=joel.granados@kernel.org \
--cc=jszhang@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=namcao@linutronix.de \
--cc=oleg@redhat.com \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=rabenda.cn@gmail.com \
--cc=samuel.holland@sifive.com \
--cc=shuah@kernel.org \
--cc=tglx@linutronix.de \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).