From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id zMvqAxGzrWrgfx0AWB0awg (envelope-from ) for ; Fri, 18 Sep 2026 17:54:25 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=KpqWWXk9; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id F35F91E04E; Fri, 18 Sep 2026 17:54:24 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 05F4C1E04E for ; Fri, 18 Sep 2026 17:54:22 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D7CDF4BB1C29 for ; Fri, 18 Sep 2026 21:54:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D7CDF4BB1C29 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1789768460; bh=l6RjwvGRDg27ocREeTOqI1wUrMM7x8CPcnaq9HAsmCs=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=KpqWWXk9o8JNXCbfX7AYq9hAjT/tJacfUd5C9TlGIZ2gAOTenmxLRuKxEkAITxc8j DRe++pu09rcHnFn/FaFU1Hu2T9lPMfNk8UxlqkaAB59u4XCvKmJN/AuvcLQnLDqIWS 3YZrILWVbD0OF0FH/mgajLAoW5MBtMcZRGHJEqUY= Received: from mail-yx2-x10.google.com (mail-yx2-x10.google.com [IPv6:2607:f8b0:4864:41::10]) by sourceware.org (Postfix) with ESMTPS id C8D8D4BB1C1C for ; Fri, 18 Sep 2026 21:53:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C8D8D4BB1C1C ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C8D8D4BB1C1C ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1789768426; cv=none; b=clbs1X0Bgxk1Oq+UUlIfgR7o0LFCxyvOTM2Zh7ca1kHrwsGXnZNbEELNSm2rsN0nOVf2g2na+tUnT69d56GmW7SLrU8tlkTOicB61LMlRM/5kHnlzUQgVU/uCHQQKVTH/MSkDEX1NEK5KVKLqkHiXUndXLOt8TCLKan4JIR7ZgE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1789768426; c=relaxed/simple; bh=jRm+QSMoN5+2+Fh9U/qdI3Fysf5TW8IchvBNfIY1DNY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=fu3muT55WBU+kVYo04u0heZMd+0zAfQap7tODVpABHD3DnOUlHRsp6pxQUr1OK0lM1ywqNRVRy4R/pV52720mV4QB5XVpRIHWE0dQO8hsMVDUORWMXGSdfw6/5UBnTTg7swvua2P4wn9OrFxW7KNbFpenTNy5WK7FYvZV7pqbIY= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=tenstorrent.com header.i=@tenstorrent.com header.a=rsa-sha256 header.s=google header.b=fEX58YO7 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C8D8D4BB1C1C Received: by mail-yx2-x10.google.com with SMTP id 00721157ae682-85d43ac8d1eso9783967b3.2 for ; Fri, 18 Sep 2026 14:53:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789768425; x=1790373225; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=l6RjwvGRDg27ocREeTOqI1wUrMM7x8CPcnaq9HAsmCs=; b=hVusUsysijViNKYlqr7modvPIrAeeAnpNmP+xZZbd+HjFgvn/aXSlXx7OaCjnMFGiR eaPHja3PHy+ZgJttMYvpSZKdwlZv7unteNTD1fbF0XC7l4CuxFh9ELMbGHDdhPFMaUPt EN61xKvcppQ+sJIjGClk1COqAuA3rOTZoOY3bkrwXqWvJjxEbUxQP86njovfF9X9oHsE l7wnjArO/z/bY/1B0+HgPNb6cAOEgmSsIjKJg1N3ZzSM2HxohLbzBXGK3zyAVIg4g+aT w8iLuhJ0f4kqltCLQR4KOHGDM+x3CvrfmE2nyLA1TI8hCjxb02soHX6/ZerP3FUwTkAZ afpQ== X-Forwarded-Encrypted: i=1; AKwUvBxEgzWpHJrN+eJ0iKjxxpWSUkwXqj01j6vu4kWzJ+7VzwHuC9+zff2UL2TeA38OQnzwGoI=@sourceware.org X-Gm-Message-State: AFuF++klpFmytGbN71mnJkSAnP0RDtNPiw0/F56SQhTXPkzIfjtwbRXu xSm/q1HYzjLqSR2jjm3miLdBk9jvdvXy6+E3fZM+C/3BUbTXkygBIpdVV5cQvfhGYvE= X-Gm-Gg: AYBFou0c0C0Yk+Cgct59HmvokxtJV4zq8OWm5RcG5uCeJxmZ0BIHkV5mWKjAslxbaaS Yzjj0uuvAmidpgabkU+yCnAkxeslbew6KAkIo3yeGjmCyQ1jClK/ivXSPrH/l3ePziHTtvyuNHL bTp9/+Vv1z8JBgnUtUQADvspWdM2pR4uzVCVyi7WVieV61fLmwHkF6d/rWK2lOusoGonD2dOqv+ luiw0YYD4ilMtwy61XOj4wN7M35KLrnKTSkBbfw8JSW3s5JJLdgWN+oTri6BmL4gq7F2GZuxDGZ CtkGt7ZVGocT0AvotzCesLTnpEZIpyMRofxqR9G097mSWupkeGu0p9uwt/TZKOXmN4dz+1gqw/1 wWGblLkKPg1ymKP6F3C+BpDJPsCWjxfjMQtXrTZF/ohlCCh1c3JbCgc4gBQkBgNNsav1InzjvnV Op5pYLwjCxy2dqeyJ4Ggj4/4+bT49hdKpajbw7POjCmKpZqtt/A8qdmewKrTM63NF49f/c6rBdf M9mJ1hx/W1OwKbOYuhRca7TNvrDpttihbfP/9NMIBCRddQ= X-Received: by 2002:a05:690c:338c:b0:858:d554:79e4 with SMTP id 00721157ae682-89732c65189mr15001397b3.20.1789768425133; Fri, 18 Sep 2026 14:53:45 -0700 (PDT) Received: from lima-default.tail89d63.ts.net ([12.55.13.134]) by smtp.gmail.com with ESMTPSA id 00721157ae682-89a45d8fb3csm4017757b3.13.2026.09.18.14.53.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Sep 2026 14:53:44 -0700 (PDT) To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Oleg Nesterov , linux-riscv@lists.infradead.org Cc: andybnac@gmail.com, Andy Chiu , Sergey Matyukevich , gdb@sourceware.org, dfustini@oss.tenstorrent.com, greentime.hu@sifive.com, Yong-Xuan Wang , daichengrong , Deepak Gupta Subject: [PATCH v6 6/8] riscv: vector: adjust ptrace and signal behavior for INITIAL state Date: Fri, 18 Sep 2026 16:51:20 -0500 Message-ID: <20260918215154.2481482-7-tchiu@tenstorrent.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260918215154.2481482-1-tchiu@tenstorrent.com> References: <20260918215154.2481482-1-tchiu@tenstorrent.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Andy Chiu via Gdb Reply-To: Andy Chiu Errors-To: gdb-bounces~public-inbox=simark.ca@sourceware.org Sender: "Gdb" The last patch introduced the INITIAL vector state to avoid saving and restoring vector registers across syscall boundaries. However, this optimization did not fully account for the ptrace and signal handling interfaces. As a result, two issues emerged: 1. Ptrace reads at syscall stop could observe stale, non-nulled registers. 2. Modifications to the ucontext through signal interface during a syscall stop would be overwritten by the vector discaring macro. This patch introduces riscv_v_ucontext_save() to synchronize these paths with the INITIAL state: - Ptrace reads during a syscall stop now explicitly execute the hardware discard macro and return the discarded state to prevent data leaks. - Ptrace writes (PTRACE_SETREGSET) during a syscall stop are silently dropped (returning 0). Returning an error like EINVAL would break debbugers like GDB, which disables the optional regset on receiving such error. - Signal handling (rt_sigreturn) now honor user-space modifications to the vector context (for user-space thread schedulers). CC: Sergey Matyukevich CC: gdb@sourceware.org Signed-off-by: Andy Chiu --- Changelog v3: - new patch since v3 --- arch/riscv/include/asm/vector.h | 2 ++ arch/riscv/kernel/ptrace.c | 13 ++++++------ arch/riscv/kernel/signal.c | 11 ++++++---- arch/riscv/kernel/vector.c | 37 +++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h index 61cd0848f661..1cc37d40cf79 100644 --- a/arch/riscv/include/asm/vector.h +++ b/arch/riscv/include/asm/vector.h @@ -61,6 +61,7 @@ void riscv_v_thread_free(struct task_struct *tsk); void __init riscv_v_setup_ctx_cache(void); void riscv_v_thread_alloc(struct task_struct *tsk); void __init update_regset_vector_info(unsigned long size); +void riscv_v_ucontext_save(struct task_struct *tsk); static inline u32 riscv_v_flags(void) { @@ -438,6 +439,7 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; } #define riscv_v_thread_alloc(tsk) do {} while (0) #define get_cpu_vector_context() do {} while (0) #define put_cpu_vector_context() do {} while (0) +#define riscv_v_ucontext_save(tsk) do {} while (0) #define riscv_v_vstate_set_restore(task, regs) do {} while (0) #endif /* CONFIG_RISCV_ISA_V */ diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c index f336a183667e..9276485b6cac 100644 --- a/arch/riscv/kernel/ptrace.c +++ b/arch/riscv/kernel/ptrace.c @@ -109,11 +109,7 @@ static int riscv_vr_get(struct task_struct *target, * Ensure the vector registers have been saved to the memory before * copying them to membuf. */ - if (target == current) { - get_cpu_vector_context(); - riscv_v_vstate_save(¤t->thread.vstate, task_pt_regs(current)); - put_cpu_vector_context(); - } + riscv_v_ucontext_save(target); ptrace_vstate.vstart = vstate->vstart; ptrace_vstate.vl = vstate->vl; @@ -222,13 +218,18 @@ static int riscv_vr_set(struct task_struct *target, int ret; struct __riscv_v_ext_state *vstate = &target->thread.vstate; struct __riscv_v_regset_state ptrace_vstate; + struct pt_regs *regs = task_pt_regs(target); if (!(has_vector() || has_xtheadvector())) return -EINVAL; - if (!riscv_v_vstate_query(task_pt_regs(target))) + if (!riscv_v_vstate_query(regs)) return -ENODATA; + /* Silently drop the modification to tracee as no vreg lives across a syscall */ + if (__riscv_v_vstate_check(regs->status, INITIAL)) + return 0; + /* Copy rest of the vstate except datap */ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ptrace_vstate, 0, sizeof(struct __riscv_v_regset_state)); diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c index 59784dc117e4..0da352310b84 100644 --- a/arch/riscv/kernel/signal.c +++ b/arch/riscv/kernel/signal.c @@ -89,9 +89,7 @@ static long save_v_state(struct pt_regs *regs, void __user *sc_vec) /* datap is designed to be 16 byte aligned for better performance */ WARN_ON(!IS_ALIGNED((unsigned long)datap, 16)); - get_cpu_vector_context(); - riscv_v_vstate_save(¤t->thread.vstate, regs); - put_cpu_vector_context(); + riscv_v_ucontext_save(current); /* Copy everything of vstate but datap. */ err = __copy_to_user(&state->v_state, ¤t->thread.vstate, @@ -121,9 +119,14 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec) /* * Mark the vstate as clean prior performing the actual copy, * to avoid getting the vstate incorrectly clobbered by the - * discarded vector state. + * discarded vector state. + * + * This also allows user to modify vregs through the signal + * interface at a syscall stop. e.g. to support user space + * context switching. */ riscv_v_vstate_set_restore(current, regs); + __riscv_v_vstate_clean(regs); /* Copy everything of __sc_riscv_v_state except datap. */ err = __copy_from_user(¤t->thread.vstate, &state->v_state, diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c index 4eef51f6d432..6fd541f5d5cb 100644 --- a/arch/riscv/kernel/vector.c +++ b/arch/riscv/kernel/vector.c @@ -29,6 +29,43 @@ static struct kmem_cache *riscv_v_kernel_cachep; unsigned long riscv_v_vsize __read_mostly; EXPORT_SYMBOL_GPL(riscv_v_vsize); +/* + * Context memory is not coherent to register when sstatus.vs is set to INITIAL. This function + * take the INITIAL state into consideration and reflect the nulled state into context memory. + * Assume the target task is not actively running when tsk != current + */ +void riscv_v_ucontext_save(struct task_struct *tsk) +{ + struct __riscv_v_ext_state *vstate = &tsk->thread.vstate; + struct pt_regs *regs = task_pt_regs(tsk); + + /* + * Do not set vstate as clean when it is INITIAL, otherwise we lose track of the nulled + * state in ptrace. + */ + if (tsk == current) { + get_cpu_vector_context(); + if (__riscv_v_vstate_check(regs->status, INITIAL)) { + riscv_v_enable(); + __riscv_v_vstate_discard(); + __riscv_v_vstate_save(vstate, vstate->datap); + riscv_v_disable(); + } else { + riscv_v_vstate_save(vstate, regs); + } + put_cpu_vector_context(); + } else if (__riscv_v_vstate_check(regs->status, INITIAL)) { + /* + * If we are not current and VS == INITIAL, null out the context memory for tsk + * using kernel mode vector. + */ + kernel_vector_begin(); + __riscv_v_vstate_discard(); + __riscv_v_vstate_save(vstate, vstate->datap); + kernel_vector_end(); + } +} + int riscv_v_setup_vsize(void) { unsigned long this_vsize; -- 2.43.0