From nobody Mon Apr 6 14:58:45 2026 Received: from cstnet.cn (smtp25.cstnet.cn [159.226.251.25]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92D1E34E743 for ; Thu, 19 Mar 2026 07:37:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773905857; cv=none; b=bnXJ0XuO8sMZ+Io2SGJ7hUxxuH7BBaH2yKxCfBLLK7mjvEi27OTOGbaedps4FOZALOGW45Mfze4IiO1BoxK7jAwUZ2Qasdn2j9gF9nFc4cdh7SvuYA/DumEN0G9YlUfX0wW5Unc+gJgekPFIxNfqs+Iecfud9VAjfMqAFuAxNwc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773905857; c=relaxed/simple; bh=pgIgn+NmepkCPWz29xJHtA7GSyYzc5r2pu5+WQYtdwA=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=qeODkuH+iKqO2JnUr8AU9Lu3icZ+3FgIOh5n8iEoh3RarcLZ5V234brT1nJtmZb3Jc5mR51nBhG8PZbdIKH/U14dVrNPAaXtcr/13jOcwHi9+ikXsQl/xsBnilUGI6eljJ4KYk1XTq3DFQ+DhILkT9SvtNIfnO7Z59w65NhC5rw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn; spf=pass smtp.mailfrom=iscas.ac.cn; arc=none smtp.client-ip=159.226.251.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iscas.ac.cn Received: from localhost.localdomain (unknown [121.237.245.153]) by APP-05 (Coremail) with SMTP id zQCowAC3Sg6op7tpCPfXCg--.53234S2; Thu, 19 Mar 2026 15:37:12 +0800 (CST) From: daichengrong To: Paul Walmsley , Palmer Dabbelt , Samuel Holland Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, daichengrong Subject: [RFC PATCH] riscv: clarify vector state semantics on syscall and context switch Date: Thu, 19 Mar 2026 15:37:09 +0800 Message-Id: <20260319073709.18562-1-daichengrong@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: zQCowAC3Sg6op7tpCPfXCg--.53234S2 X-Coremail-Antispam: 1UD129KBjvJXoWxur47ZFy5Ww1kArW5CryfWFg_yoW5Arykpr Z8Cr43CrWUGa1xZr9Fqw48XrZ5G3yrW3y5ArZxGayrGF1fKr93CFn5t34qvFWDJFyFkFyj yayvg348Zw4DArUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUvq14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j 6F4UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s 0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xII jxv20xvE14v26r1Y6r17McIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S6xCaFVCjc4AY6r1j6r 4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY1x0262kKe7AKxVWU AVWUtwCY02Avz4vE14v_GF4l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr 1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE 14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7 IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E 87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0x ZFpf9x0JU92-nUUUUU= X-CM-SenderInfo: pgdluxxhqj201qj6x2xfdvhtffof0/ Content-Type: text/plain; charset="utf-8" The RISC-V vector specification states that executing a system call causes all caller-saved vector registers (v0-v31, vl, vtype) and vstart to become unspecified. Currently, after calling riscv_v_vstate_discard(), the vector state=20 may still be marked as DIRTY, which can mislead the context switch=20 logic into treating the registers as containing valid user data. This patch clarifies and tightens the kernel-side semantics: 1. On syscall entry, the kernel checks the vector state via mstatus and discards it if necessary. After discard, the state is explicitly set to INIT instead of DIRTY, indicating that the vector registers no longer contain meaningful user data. 2. During context switch, the vector state is interpreted as follows: - INIT: no valid user data is present, so vector register data does not need to be saved. - non-INIT (e.g. DIRTY): vector register data must be saved. 3. On restore, if the state is INIT, the vector registers are treated as invalid and are not restored from memory. Instead, they are overwritten with a known initial value to avoid potential data leakage from a previous task. This aligns the kernel's vector state tracking with the architectural "unspecified" semantics while ensuring correct lazy context switching and preventing cross-task data leakage. Signed-off-by: daichengrong --- arch/riscv/include/asm/vector.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vecto= r.h index 00cb9c0982b1..93c68a549b72 100644 --- a/arch/riscv/include/asm/vector.h +++ b/arch/riscv/include/asm/vector.h @@ -298,8 +298,9 @@ static inline void __riscv_v_vstate_discard(void) static inline void riscv_v_vstate_discard(struct pt_regs *regs) { if (riscv_v_vstate_query(regs)) { - __riscv_v_vstate_discard(); - __riscv_v_vstate_dirty(regs); + if (!__riscv_v_vstate_check(regs->status, INITIAL)) + __riscv_v_vstate_discard(); + riscv_v_vstate_on(regs); } } =20 @@ -315,19 +316,17 @@ static inline void riscv_v_vstate_save(struct __riscv= _v_ext_state *vstate, static inline void riscv_v_vstate_restore(struct __riscv_v_ext_state *vsta= te, struct pt_regs *regs) { - if (riscv_v_vstate_query(regs)) { + if (__riscv_v_vstate_check(regs->status, INITIAL)) + __riscv_v_vstate_discard(); + else if (__riscv_v_vstate_check(regs->status, CLEAN)) __riscv_v_vstate_restore(vstate, vstate->datap); - __riscv_v_vstate_clean(regs); - } } =20 static inline void riscv_v_vstate_set_restore(struct task_struct *task, struct pt_regs *regs) { - if (riscv_v_vstate_query(regs)) { + if (riscv_v_vstate_query(regs)) set_tsk_thread_flag(task, TIF_RISCV_V_DEFER_RESTORE); - riscv_v_vstate_on(regs); - } } =20 #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE --=20 2.25.1