From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281710082538.3630241689424; Sun, 12 Oct 2025 08:08:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfe-0001i7-0T; Sun, 12 Oct 2025 11:07:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfR-0001eI-5s; Sun, 12 Oct 2025 11:07:25 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfL-0001cw-T7; Sun, 12 Oct 2025 11:07:24 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwDX32MZxOtofE6gAA--.44S2; Sun, 12 Oct 2025 23:07:05 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S4; Sun, 12 Oct 2025 23:07:04 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 01/21] hw/arm/smmuv3: Fix incorrect reserved mask for SMMU CR0 register Date: Sun, 12 Oct 2025 23:06:41 +0800 Message-Id: <20251012150701.4127034-2-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S4 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBVQAAsk Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvdXoWrZry5Ar43ZFW5GryDXw17GFg_yoWDtwbEkF s7Jay8Wr4UKFWDX3W8KFWSyry093y5WrZ5XF1xtFn8KFZ8Xa45WFs7Z3s5Z34fGFy8uFya kanFyrWag39rujkaLaAFLSUrUUUUbb8apTn2vfkv8UJUUUU8wcxFpf9Il3svdxBIdaVrnU Uv73VFW2AGmfu7jjvjm3AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUU UUUU= Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281722444158500 Content-Type: text/plain; charset="utf-8" The current definition of the SMMU_CR0_RESERVED mask is incorrect. It mistakenly treats bit 10 (DPT_WALK_EN) as a reserved bit while treating bit 9 (RES0) as an implemented bit. According to the SMMU architecture specification, the layout for CR0 is: | 31:11| RES0 | | 10 | DPT_WALK_EN | | 9 | RES0 | | 8:6 | VMW | | 5 | RES0 | | 4 | ATSCHK | | 3 | CMDQEN | | 2 | EVENTQEN | | 1 | PRIQEN | | 0 | SMMUEN | Signed-off-by: Tao Tang Reviewed-by: Eric Auger Link: https://lists.gnu.org/archive/html/qemu-arm/2025-06/msg00088.html --- hw/arm/smmuv3-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index b6b7399347..42ac77e654 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -120,7 +120,7 @@ REG32(CR0, 0x20) FIELD(CR0, EVENTQEN, 2, 1) FIELD(CR0, CMDQEN, 3, 1) =20 -#define SMMU_CR0_RESERVED 0xFFFFFC20 +#define SMMU_CR0_RESERVED 0xFFFFFA20 =20 REG32(CR0ACK, 0x24) REG32(CR1, 0x28) --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281713393512.1112533466536; Sun, 12 Oct 2025 08:08:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfR-0001eG-Jz; Sun, 12 Oct 2025 11:07:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfP-0001ch-J0; Sun, 12 Oct 2025 11:07:23 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfK-0001cv-Uc; Sun, 12 Oct 2025 11:07:23 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwCHj5saxOtohE6gAA--.38S2; Sun, 12 Oct 2025 23:07:06 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S5; Sun, 12 Oct 2025 23:07:05 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 02/21] hw/arm/smmuv3: Correct SMMUEN field name in CR0 Date: Sun, 12 Oct 2025 23:06:42 +0800 Message-Id: <20251012150701.4127034-3-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S5 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBVwAAsm Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7Jr47Xr1xXw4furyxury7GFg_yoW8Jry8pF 4kGF1rGrWUAa4S9ryxGay7AF15Wayktr1UKr97G3sxJ3WavFZxAryvkF1DWFykuryUXF4r u3Z2ya409a1IyrJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281718969158500 Content-Type: text/plain; charset="utf-8" The FIELD macro for the SMMU enable bit in the CR0 register was incorrectly named SMMU_ENABLE. The ARM SMMUv3 Architecture Specification (both older IHI 0070.E.a and newer IHI 0070.G.b) consistently refers to the SMMU enable bit as SMMUEN. This change makes our implementation consistent with the manual. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Link: https://lists.nongnu.org/archive/html/qemu-arm/2025-09/msg01270.html --- hw/arm/smmuv3-internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index 42ac77e654..8d631ecf27 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -116,7 +116,7 @@ REG32(IDR5, 0x14) REG32(IIDR, 0x18) REG32(AIDR, 0x1c) REG32(CR0, 0x20) - FIELD(CR0, SMMU_ENABLE, 0, 1) + FIELD(CR0, SMMUEN, 0, 1) FIELD(CR0, EVENTQEN, 2, 1) FIELD(CR0, CMDQEN, 3, 1) =20 @@ -181,7 +181,7 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) =20 static inline int smmu_enabled(SMMUv3State *s) { - return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE); + return FIELD_EX32(s->cr[0], CR0, SMMUEN); } =20 /* Command Queue Entry */ --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281788140143.133688689241; Sun, 12 Oct 2025 08:09:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfQ-0001by-75; Sun, 12 Oct 2025 11:07:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfN-0001ap-I2; Sun, 12 Oct 2025 11:07:21 -0400 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfK-0001cr-LE; Sun, 12 Oct 2025 11:07:21 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwCnrCQaxOtoXycrAA--.7708S2; Sun, 12 Oct 2025 23:07:06 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S6; Sun, 12 Oct 2025 23:07:05 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 03/21] hw/arm/smmuv3: Introduce secure registers Date: Sun, 12 Oct 2025 23:06:43 +0800 Message-Id: <20251012150701.4127034-4-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S6 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBWQAAso Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxWr45WryUGFWrAw1kJr1DZFb_yoW5CF45pr W0yF1rC3yDXF4xXw1fGa1UAF13Crs5AFyUGFZFkr1aga4fWry3ArW8Ka4fGrykWF1rZF4D G3Wqv34F934Syr7anT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=209.97.181.73; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281797369158500 Content-Type: text/plain; charset="utf-8" The Arm SMMUv3 architecture defines a set of registers for managing secure transactions and context. This patch introduces the definitions for these secure registers within the SMMUv3 device model internal header. Signed-off-by: Tao Tang --- hw/arm/smmuv3-internal.h | 69 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index 8d631ecf27..e420c5dc72 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -38,7 +38,7 @@ typedef enum SMMUTranslationClass { SMMU_CLASS_IN, } SMMUTranslationClass; =20 -/* MMIO Registers */ +/* MMIO Registers. Shared by Non-secure/Realm/Root states. */ =20 REG32(IDR0, 0x0) FIELD(IDR0, S2P, 0 , 1) @@ -121,6 +121,7 @@ REG32(CR0, 0x20) FIELD(CR0, CMDQEN, 3, 1) =20 #define SMMU_CR0_RESERVED 0xFFFFFA20 +#define SMMU_S_CR0_RESERVED 0xFFFFFC12 =20 REG32(CR0ACK, 0x24) REG32(CR1, 0x28) @@ -179,6 +180,72 @@ REG32(EVENTQ_IRQ_CFG2, 0xbc) =20 #define A_IDREGS 0xfd0 =20 +#define SMMU_SECURE_REG_START 0x8000 /* Start of secure-only registers */ + +REG32(S_IDR0, 0x8000) +REG32(S_IDR1, 0x8004) + FIELD(S_IDR1, S_SIDSIZE, 0 , 6) + FIELD(S_IDR1, SEL2, 29, 1) + FIELD(S_IDR1, SECURE_IMPL, 31, 1) + +REG32(S_IDR2, 0x8008) +REG32(S_IDR3, 0x800c) +REG32(S_IDR4, 0x8010) + +REG32(S_CR0, 0x8020) + FIELD(S_CR0, SMMUEN, 0, 1) + FIELD(S_CR0, EVENTQEN, 2, 1) + FIELD(S_CR0, CMDQEN, 3, 1) + +REG32(S_CR0ACK, 0x8024) +REG32(S_CR1, 0x8028) +REG32(S_CR2, 0x802c) + +REG32(S_INIT, 0x803c) + FIELD(S_INIT, INV_ALL, 0, 1) + +REG32(S_GBPA, 0x8044) + FIELD(S_GBPA, ABORT, 20, 1) + FIELD(S_GBPA, UPDATE, 31, 1) + +REG32(S_IRQ_CTRL, 0x8050) + FIELD(S_IRQ_CTRL, GERROR_IRQEN, 0, 1) + FIELD(S_IRQ_CTRL, EVENTQ_IRQEN, 2, 1) + +REG32(S_IRQ_CTRLACK, 0x8054) + +REG32(S_GERROR, 0x8060) + FIELD(S_GERROR, CMDQ_ERR, 0, 1) + +#define SMMU_GERROR_IRQ_CFG0_RESERVED 0x00FFFFFFFFFFFFFC +#define SMMU_GERROR_IRQ_CFG2_RESERVED 0x000000000000003F + +#define SMMU_STRTAB_BASE_RESERVED 0x40FFFFFFFFFFFFC0 +#define SMMU_QUEUE_BASE_RESERVED 0x40FFFFFFFFFFFFFF +#define SMMU_EVENTQ_IRQ_CFG0_RESERVED 0x00FFFFFFFFFFFFFC + +REG32(S_GERRORN, 0x8064) +REG64(S_GERROR_IRQ_CFG0, 0x8068) +REG32(S_GERROR_IRQ_CFG1, 0x8070) +REG32(S_GERROR_IRQ_CFG2, 0x8074) +REG64(S_STRTAB_BASE, 0x8080) +REG32(S_STRTAB_BASE_CFG, 0x8088) + FIELD(S_STRTAB_BASE_CFG, LOG2SIZE, 0, 6) + FIELD(S_STRTAB_BASE_CFG, SPLIT, 6, 5) + FIELD(S_STRTAB_BASE_CFG, FMT, 16, 2) + +REG64(S_CMDQ_BASE, 0x8090) +REG32(S_CMDQ_PROD, 0x8098) +REG32(S_CMDQ_CONS, 0x809c) + FIELD(S_CMDQ_CONS, ERR, 24, 7) + +REG64(S_EVENTQ_BASE, 0x80a0) +REG32(S_EVENTQ_PROD, 0x80a8) +REG32(S_EVENTQ_CONS, 0x80ac) +REG64(S_EVENTQ_IRQ_CFG0, 0x80b0) +REG32(S_EVENTQ_IRQ_CFG1, 0x80b8) +REG32(S_EVENTQ_IRQ_CFG2, 0x80bc) + static inline int smmu_enabled(SMMUv3State *s) { return FIELD_EX32(s->cr[0], CR0, SMMUEN); --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281766727369.4979471896279; Sun, 12 Oct 2025 08:09:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfb-0001hO-AN; Sun, 12 Oct 2025 11:07:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfP-0001d3-Mw; Sun, 12 Oct 2025 11:07:23 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfL-0001cm-E4; Sun, 12 Oct 2025 11:07:23 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwBHKCUcxOtoZycrAA--.7486S2; Sun, 12 Oct 2025 23:07:08 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S7; Sun, 12 Oct 2025 23:07:06 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 04/21] refactor: Move ARMSecuritySpace to a common header Date: Sun, 12 Oct 2025 23:06:44 +0800 Message-Id: <20251012150701.4127034-5-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S7 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBWwAAsq Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxXF45CF1xJr1fJF4kJryDAwb_yoWrurW7pF 4Yyas3Gr48Ga43Gas3ZFsrGF1rK395WF47KFyxWr4kXFnxur1kCr4vyF1YkFy5GrW5Z3WF 9r1xZr4fKF1kXrJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=162.243.164.118; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmtyylji0my4xnjqumte4.icoremail.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281768399154100 Content-Type: text/plain; charset="utf-8" The ARMSecuritySpace enum and its related helpers were defined in the target-specific header target/arm/cpu.h. This prevented common, target-agnostic code like the SMMU model from using these definitions without triggering "cpu.h included from common code" errors. To resolve this, this commit introduces a new, lightweight header, include/hw/arm/arm-security.h, which is safe for inclusion by common code. The following change was made: - The ARMSecuritySpace enum and the arm_space_is_secure() and arm_secure_to_space() helpers have been moved from target/arm/cpu.h to the new hw/arm/arm-security.h header. This refactoring decouples the security state definitions from the core CPU implementation, allowing common hardware models to correctly handle security states without pulling in heavyweight, target-specific headers. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Link: https://lists.nongnu.org/archive/html/qemu-arm/2025-09/msg01288.html --- include/hw/arm/arm-security.h | 54 +++++++++++++++++++++++++++++++++++ target/arm/cpu.h | 25 +--------------- 2 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 include/hw/arm/arm-security.h diff --git a/include/hw/arm/arm-security.h b/include/hw/arm/arm-security.h new file mode 100644 index 0000000000..9664c0f95e --- /dev/null +++ b/include/hw/arm/arm-security.h @@ -0,0 +1,54 @@ +/* + * ARM security space helpers + * + * Provide ARMSecuritySpace and helpers for code that is not tied to CPU. + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef HW_ARM_ARM_SECURITY_H +#define HW_ARM_ARM_SECURITY_H + +#include + +/* + * ARM v9 security states. + * The ordering of the enumeration corresponds to the low 2 bits + * of the GPI value, and (except for Root) the concat of NSE:NS. + */ + + typedef enum ARMSecuritySpace { + ARMSS_Secure =3D 0, + ARMSS_NonSecure =3D 1, + ARMSS_Root =3D 2, + ARMSS_Realm =3D 3, +} ARMSecuritySpace; + +/* Return true if @space is secure, in the pre-v9 sense. */ +static inline bool arm_space_is_secure(ARMSecuritySpace space) +{ + return space =3D=3D ARMSS_Secure || space =3D=3D ARMSS_Root; +} + +/* Return the ARMSecuritySpace for @secure, assuming !RME or EL[0-2]. */ +static inline ARMSecuritySpace arm_secure_to_space(bool secure) +{ + return secure ? ARMSS_Secure : ARMSS_NonSecure; +} + +#endif /* HW_ARM_ARM_SECURITY_H */ + + diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 1d4e13320c..3336d95c6a 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -31,6 +31,7 @@ #include "exec/page-protection.h" #include "qapi/qapi-types-common.h" #include "target/arm/multiprocessing.h" +#include "hw/arm/arm-security.h" #include "target/arm/gtimer.h" #include "target/arm/cpu-sysregs.h" #include "target/arm/mmuidx.h" @@ -2098,30 +2099,6 @@ static inline int arm_feature(CPUARMState *env, int = feature) =20 void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp); =20 -/* - * ARM v9 security states. - * The ordering of the enumeration corresponds to the low 2 bits - * of the GPI value, and (except for Root) the concat of NSE:NS. - */ - -typedef enum ARMSecuritySpace { - ARMSS_Secure =3D 0, - ARMSS_NonSecure =3D 1, - ARMSS_Root =3D 2, - ARMSS_Realm =3D 3, -} ARMSecuritySpace; - -/* Return true if @space is secure, in the pre-v9 sense. */ -static inline bool arm_space_is_secure(ARMSecuritySpace space) -{ - return space =3D=3D ARMSS_Secure || space =3D=3D ARMSS_Root; -} - -/* Return the ARMSecuritySpace for @secure, assuming !RME or EL[0-2]. */ -static inline ARMSecuritySpace arm_secure_to_space(bool secure) -{ - return secure ? ARMSS_Secure : ARMSS_NonSecure; -} =20 #if !defined(CONFIG_USER_ONLY) /** --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281745353639.7862746166253; Sun, 12 Oct 2025 08:09:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfo-0001lx-QK; Sun, 12 Oct 2025 11:07:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfU-0001gP-7s; Sun, 12 Oct 2025 11:07:29 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfL-0001cx-Sn; Sun, 12 Oct 2025 11:07:27 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwCXn1McxOtoYycrAA--.7417S2; Sun, 12 Oct 2025 23:07:08 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S8; Sun, 12 Oct 2025 23:07:07 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 05/21] hw/arm/smmuv3: Introduce banked registers for SMMUv3 state Date: Sun, 12 Oct 2025 23:06:45 +0800 Message-Id: <20251012150701.4127034-6-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S8 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBWwABsr Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoWfZw1xCF1ftw4UXF18trWDJwb_yoW5Cw4rWo WSyFnFqa1DZw4DC340kFn5XF10qFWUCw4qqa1YvrWa9FsrGw4rGryxKr4rCF909F45JrWk Aw4xu3yrZF40vFn5n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3UbIjqfuFe4nvWSU8nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UU UUUUUUU== Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281753101158500 Content-Type: text/plain; charset="utf-8" Rework the SMMUv3 state management by introducing a banked register structure. This is a purely mechanical refactoring with no functional changes. To support multiple security states, a new enum, SMMUSecSID, is introduced to identify each state, sticking to the spec terminology. A new structure, SMMUv3RegBank, is then defined to hold the state for a single security context. The main SMMUv3State now contains an array of these banks, indexed by SMMUSecSID. This avoids the need for separate fields for non-secure and future secure registers. All existing code, which handles only the Non-secure state, is updated to access its state via s->bank[SMMU_SEC_SID_NS]. A local bank helper pointer is used where it improves readability. Function signatures and logic remain untouched in this commit to isolate the structural changes and simplify review. This is the foundational step for building multi-security-state support. Signed-off-by: Tao Tang --- hw/arm/smmuv3-internal.h | 24 ++- hw/arm/smmuv3.c | 344 +++++++++++++++++++---------------- include/hw/arm/smmu-common.h | 6 + include/hw/arm/smmuv3.h | 38 +++- 4 files changed, 239 insertions(+), 173 deletions(-) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index e420c5dc72..858bc206a2 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -248,7 +248,9 @@ REG32(S_EVENTQ_IRQ_CFG2, 0x80bc) =20 static inline int smmu_enabled(SMMUv3State *s) { - return FIELD_EX32(s->cr[0], CR0, SMMUEN); + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + return FIELD_EX32(bank->cr[0], CR0, SMMUEN); } =20 /* Command Queue Entry */ @@ -276,12 +278,16 @@ static inline uint32_t smmuv3_idreg(int regoffset) =20 static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s) { - return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN); + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + return FIELD_EX32(bank->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN); } =20 static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s) { - return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN); + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + return FIELD_EX32(bank->irq_ctrl, IRQ_CTRL, GERROR_IRQEN); } =20 /* Queue Handling */ @@ -326,17 +332,23 @@ static inline void queue_cons_incr(SMMUQueue *q) =20 static inline bool smmuv3_cmdq_enabled(SMMUv3State *s) { - return FIELD_EX32(s->cr[0], CR0, CMDQEN); + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + return FIELD_EX32(bank->cr[0], CR0, CMDQEN); } =20 static inline bool smmuv3_eventq_enabled(SMMUv3State *s) { - return FIELD_EX32(s->cr[0], CR0, EVENTQEN); + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + return FIELD_EX32(bank->cr[0], CR0, EVENTQEN); } =20 static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type) { - s->cmdq.cons =3D FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type); + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + bank->cmdq.cons =3D FIELD_DP32(bank->cmdq.cons, CMDQ_CONS, ERR, err_ty= pe); } =20 /* Commands */ diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index bcf8af8dc7..9c085ac678 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -50,6 +50,8 @@ static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask) { + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); =20 bool pulse =3D false; =20 @@ -65,15 +67,15 @@ static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq = irq, break; case SMMU_IRQ_GERROR: { - uint32_t pending =3D s->gerror ^ s->gerrorn; + uint32_t pending =3D bank->gerror ^ bank->gerrorn; uint32_t new_gerrors =3D ~pending & gerror_mask; =20 if (!new_gerrors) { /* only toggle non pending errors */ return; } - s->gerror ^=3D new_gerrors; - trace_smmuv3_write_gerror(new_gerrors, s->gerror); + bank->gerror ^=3D new_gerrors; + trace_smmuv3_write_gerror(new_gerrors, bank->gerror); =20 pulse =3D smmuv3_gerror_irq_enabled(s); break; @@ -87,8 +89,10 @@ static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq i= rq, =20 static void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn) { - uint32_t pending =3D s->gerror ^ s->gerrorn; - uint32_t toggled =3D s->gerrorn ^ new_gerrorn; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + uint32_t pending =3D bank->gerror ^ bank->gerrorn; + uint32_t toggled =3D bank->gerrorn ^ new_gerrorn; =20 if (toggled & ~pending) { qemu_log_mask(LOG_GUEST_ERROR, @@ -100,9 +104,9 @@ static void smmuv3_write_gerrorn(SMMUv3State *s, uint32= _t new_gerrorn) * We do not raise any error in case guest toggles bits corresponding * to not active IRQs (CONSTRAINED UNPREDICTABLE) */ - s->gerrorn =3D new_gerrorn; + bank->gerrorn =3D new_gerrorn; =20 - trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn); + trace_smmuv3_write_gerrorn(toggled & pending, bank->gerrorn); } =20 static inline MemTxResult queue_read(SMMUQueue *q, Cmd *cmd) @@ -144,7 +148,9 @@ static MemTxResult queue_write(SMMUQueue *q, Evt *evt_i= n) =20 static MemTxResult smmuv3_write_eventq(SMMUv3State *s, Evt *evt) { - SMMUQueue *q =3D &s->eventq; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + SMMUQueue *q =3D &bank->eventq; MemTxResult r; =20 if (!smmuv3_eventq_enabled(s)) { @@ -259,64 +265,66 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInf= o *info) =20 static void smmuv3_init_regs(SMMUv3State *s) { + SMMUv3RegBank *bk =3D smmuv3_bank_ns(s); + /* Based on sys property, the stages supported in smmu will be adverti= sed.*/ if (s->stage && !strcmp("2", s->stage)) { - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, S2P, 1); + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, S2P, 1); } else if (s->stage && !strcmp("nested", s->stage)) { - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, S1P, 1); - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, S2P, 1); + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, S1P, 1); + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, S2P, 1); } else { - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, S1P, 1); + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, S1P, 1); } =20 - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only= */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, VMID16, 1); /* 16-bit VMID */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endi= an */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall= */ + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, TTF, 2); /* AArch64 PTW on= ly */ + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, COHACC, 1); /* IO coherent= */ + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, ASID16, 1); /* 16-bit ASID= */ + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, VMID16, 1); /* 16-bit VMID= */ + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, TTENDIAN, 2); /* little en= dian */ + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, STALL_MODEL, 1); /* No sta= ll */ /* terminated transaction will always be aborted/error returned */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, TERM_MODEL, 1); + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, TERM_MODEL, 1); /* 2-level stream table supported */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, STLEVEL, 1); + bk->idr[0] =3D FIELD_DP32(bk->idr[0], IDR0, STLEVEL, 1); =20 - s->idr[1] =3D FIELD_DP32(s->idr[1], IDR1, SIDSIZE, SMMU_IDR1_SIDSIZE); - s->idr[1] =3D FIELD_DP32(s->idr[1], IDR1, EVENTQS, SMMU_EVENTQS); - s->idr[1] =3D FIELD_DP32(s->idr[1], IDR1, CMDQS, SMMU_CMDQS); + bk->idr[1] =3D FIELD_DP32(bk->idr[1], IDR1, SIDSIZE, SMMU_IDR1_SIDSIZE= ); + bk->idr[1] =3D FIELD_DP32(bk->idr[1], IDR1, EVENTQS, SMMU_EVENTQS); + bk->idr[1] =3D FIELD_DP32(bk->idr[1], IDR1, CMDQS, SMMU_CMDQS); =20 - s->idr[3] =3D FIELD_DP32(s->idr[3], IDR3, HAD, 1); - if (FIELD_EX32(s->idr[0], IDR0, S2P)) { + bk->idr[3] =3D FIELD_DP32(bk->idr[3], IDR3, HAD, 1); + if (FIELD_EX32(bk->idr[0], IDR0, S2P)) { /* XNX is a stage-2-specific feature */ - s->idr[3] =3D FIELD_DP32(s->idr[3], IDR3, XNX, 1); + bk->idr[3] =3D FIELD_DP32(bk->idr[3], IDR3, XNX, 1); } - s->idr[3] =3D FIELD_DP32(s->idr[3], IDR3, RIL, 1); - s->idr[3] =3D FIELD_DP32(s->idr[3], IDR3, BBML, 2); + bk->idr[3] =3D FIELD_DP32(bk->idr[3], IDR3, RIL, 1); + bk->idr[3] =3D FIELD_DP32(bk->idr[3], IDR3, BBML, 2); =20 - s->idr[5] =3D FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 b= its */ + bk->idr[5] =3D FIELD_DP32(bk->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44= bits */ /* 4K, 16K and 64K granule support */ - s->idr[5] =3D FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1); - s->idr[5] =3D FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1); - s->idr[5] =3D FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1); - - s->cmdq.base =3D deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS); - s->cmdq.prod =3D 0; - s->cmdq.cons =3D 0; - s->cmdq.entry_size =3D sizeof(struct Cmd); - s->eventq.base =3D deposit64(s->eventq.base, 0, 5, SMMU_EVENTQS); - s->eventq.prod =3D 0; - s->eventq.cons =3D 0; - s->eventq.entry_size =3D sizeof(struct Evt); - - s->features =3D 0; - s->sid_split =3D 0; + bk->idr[5] =3D FIELD_DP32(bk->idr[5], IDR5, GRAN4K, 1); + bk->idr[5] =3D FIELD_DP32(bk->idr[5], IDR5, GRAN16K, 1); + bk->idr[5] =3D FIELD_DP32(bk->idr[5], IDR5, GRAN64K, 1); + + bk->cmdq.base =3D deposit64(bk->cmdq.base, 0, 5, SMMU_CMDQS); + bk->cmdq.prod =3D 0; + bk->cmdq.cons =3D 0; + bk->cmdq.entry_size =3D sizeof(struct Cmd); + bk->eventq.base =3D deposit64(bk->eventq.base, 0, 5, SMMU_EVENTQS); + bk->eventq.prod =3D 0; + bk->eventq.cons =3D 0; + bk->eventq.entry_size =3D sizeof(struct Evt); + + bk->features =3D 0; + bk->sid_split =3D 0; s->aidr =3D 0x1; - s->cr[0] =3D 0; - s->cr0ack =3D 0; - s->irq_ctrl =3D 0; - s->gerror =3D 0; - s->gerrorn =3D 0; + bk->cr[0] =3D 0; + bk->cr0ack =3D 0; + bk->irq_ctrl =3D 0; + bk->gerror =3D 0; + bk->gerrorn =3D 0; s->statusr =3D 0; - s->gbpa =3D SMMU_GBPA_RESET_VAL; + bk->gbpa =3D SMMU_GBPA_RESET_VAL; } =20 static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, @@ -430,7 +438,7 @@ static bool s2_pgtable_config_valid(uint8_t sl0, uint8_= t t0sz, uint8_t gran) static int decode_ste_s2_cfg(SMMUv3State *s, SMMUTransCfg *cfg, STE *ste) { - uint8_t oas =3D FIELD_EX32(s->idr[5], IDR5, OAS); + uint8_t oas =3D FIELD_EX32(smmuv3_bank_ns(s)->idr[5], IDR5, OAS); =20 if (STE_S2AA64(ste) =3D=3D 0x0) { qemu_log_mask(LOG_UNIMP, @@ -548,7 +556,8 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg, STE *ste, SMMUEventInfo *event) { uint32_t config; - uint8_t oas =3D FIELD_EX32(s->idr[5], IDR5, OAS); + /* OAS is shared between S and NS and only present on NS-IDR5 */ + uint8_t oas =3D FIELD_EX32(smmuv3_bank_ns(s)->idr[5], IDR5, OAS); int ret; =20 if (!STE_VALID(ste)) { @@ -636,9 +645,11 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid,= STE *ste, uint32_t log2size; int strtab_size_shift; int ret; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); =20 - trace_smmuv3_find_ste(sid, s->features, s->sid_split); - log2size =3D FIELD_EX32(s->strtab_base_cfg, STRTAB_BASE_CFG, LOG2SIZE); + trace_smmuv3_find_ste(sid, bank->features, bank->sid_split); + log2size =3D FIELD_EX32(bank->strtab_base_cfg, STRTAB_BASE_CFG, LOG2SI= ZE); /* * Check SID range against both guest-configured and implementation li= mits */ @@ -646,7 +657,7 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, = STE *ste, event->type =3D SMMU_EVT_C_BAD_STREAMID; return -EINVAL; } - if (s->features & SMMU_FEATURE_2LVL_STE) { + if (bank->features & SMMU_FEATURE_2LVL_STE) { int l1_ste_offset, l2_ste_offset, max_l2_ste, span, i; dma_addr_t l1ptr, l2ptr; STEDesc l1std; @@ -655,11 +666,11 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid= , STE *ste, * Align strtab base address to table size. For this purpose, assu= me it * is not bounded by SMMU_IDR1_SIDSIZE. */ - strtab_size_shift =3D MAX(5, (int)log2size - s->sid_split - 1 + 3); - strtab_base =3D s->strtab_base & SMMU_BASE_ADDR_MASK & + strtab_size_shift =3D MAX(5, (int)log2size - bank->sid_split - 1 += 3); + strtab_base =3D bank->strtab_base & SMMU_BASE_ADDR_MASK & ~MAKE_64BIT_MASK(0, strtab_size_shift); - l1_ste_offset =3D sid >> s->sid_split; - l2_ste_offset =3D sid & ((1 << s->sid_split) - 1); + l1_ste_offset =3D sid >> bank->sid_split; + l2_ste_offset =3D sid & ((1 << bank->sid_split) - 1); l1ptr =3D (dma_addr_t)(strtab_base + l1_ste_offset * sizeof(l1std)= ); /* TODO: guarantee 64-bit single-copy atomicity */ ret =3D dma_memory_read(&address_space_memory, l1ptr, &l1std, @@ -688,7 +699,7 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, = STE *ste, } max_l2_ste =3D (1 << span) - 1; l2ptr =3D l1std_l2ptr(&l1std); - trace_smmuv3_find_ste_2lvl(s->strtab_base, l1ptr, l1_ste_offset, + trace_smmuv3_find_ste_2lvl(bank->strtab_base, l1ptr, l1_ste_offset, l2ptr, l2_ste_offset, max_l2_ste); if (l2_ste_offset > max_l2_ste) { qemu_log_mask(LOG_GUEST_ERROR, @@ -700,7 +711,7 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, = STE *ste, addr =3D l2ptr + l2_ste_offset * sizeof(*ste); } else { strtab_size_shift =3D log2size + 5; - strtab_base =3D s->strtab_base & SMMU_BASE_ADDR_MASK & + strtab_base =3D bank->strtab_base & SMMU_BASE_ADDR_MASK & ~MAKE_64BIT_MASK(0, strtab_size_shift); addr =3D strtab_base + sid * sizeof(*ste); } @@ -719,7 +730,7 @@ static int decode_cd(SMMUv3State *s, SMMUTransCfg *cfg, int i; SMMUTranslationStatus status; SMMUTLBEntry *entry; - uint8_t oas =3D FIELD_EX32(s->idr[5], IDR5, OAS); + uint8_t oas =3D FIELD_EX32(smmuv3_bank_ns(s)->idr[5], IDR5, OAS); =20 if (!CD_VALID(cd) || !CD_AARCH64(cd)) { goto bad_cd; @@ -1041,6 +1052,8 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegi= on *mr, hwaddr addr, SMMUDevice *sdev =3D container_of(mr, SMMUDevice, iommu); SMMUv3State *s =3D sdev->smmu; uint32_t sid =3D smmu_get_sid(sdev); + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); SMMUEventInfo event =3D {.type =3D SMMU_EVT_NONE, .sid =3D sid, .inval_ste_allowed =3D false}; @@ -1058,7 +1071,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegi= on *mr, hwaddr addr, qemu_mutex_lock(&s->mutex); =20 if (!smmu_enabled(s)) { - if (FIELD_EX32(s->gbpa, GBPA, ABORT)) { + if (FIELD_EX32(bank->gbpa, GBPA, ABORT)) { status =3D SMMU_TRANS_ABORT; } else { status =3D SMMU_TRANS_DISABLE; @@ -1282,7 +1295,9 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) { SMMUState *bs =3D ARM_SMMU(s); SMMUCmdError cmd_error =3D SMMU_CERROR_NONE; - SMMUQueue *q =3D &s->cmdq; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + SMMUQueue *q =3D &bank->cmdq; SMMUCommandType type =3D 0; =20 if (!smmuv3_cmdq_enabled(s)) { @@ -1296,7 +1311,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) */ =20 while (!smmuv3_q_empty(q)) { - uint32_t pending =3D s->gerror ^ s->gerrorn; + uint32_t pending =3D bank->gerror ^ bank->gerrorn; Cmd cmd; =20 trace_smmuv3_cmdq_consume(Q_PROD(q), Q_CONS(q), @@ -1511,29 +1526,32 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset, uint64_t data, MemTxAttrs attrs) { + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + switch (offset) { case A_GERROR_IRQ_CFG0: - s->gerror_irq_cfg0 =3D data; + bank->gerror_irq_cfg0 =3D data; return MEMTX_OK; case A_STRTAB_BASE: - s->strtab_base =3D data; + bank->strtab_base =3D data; return MEMTX_OK; case A_CMDQ_BASE: - s->cmdq.base =3D data; - s->cmdq.log2size =3D extract64(s->cmdq.base, 0, 5); - if (s->cmdq.log2size > SMMU_CMDQS) { - s->cmdq.log2size =3D SMMU_CMDQS; + bank->cmdq.base =3D data; + bank->cmdq.log2size =3D extract64(bank->cmdq.base, 0, 5); + if (bank->cmdq.log2size > SMMU_CMDQS) { + bank->cmdq.log2size =3D SMMU_CMDQS; } return MEMTX_OK; case A_EVENTQ_BASE: - s->eventq.base =3D data; - s->eventq.log2size =3D extract64(s->eventq.base, 0, 5); - if (s->eventq.log2size > SMMU_EVENTQS) { - s->eventq.log2size =3D SMMU_EVENTQS; + bank->eventq.base =3D data; + bank->eventq.log2size =3D extract64(bank->eventq.base, 0, 5); + if (bank->eventq.log2size > SMMU_EVENTQS) { + bank->eventq.log2size =3D SMMU_EVENTQS; } return MEMTX_OK; case A_EVENTQ_IRQ_CFG0: - s->eventq_irq_cfg0 =3D data; + bank->eventq_irq_cfg0 =3D data; return MEMTX_OK; default: qemu_log_mask(LOG_UNIMP, @@ -1546,21 +1564,24 @@ static MemTxResult smmu_writell(SMMUv3State *s, hwa= ddr offset, static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset, uint64_t data, MemTxAttrs attrs) { + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + switch (offset) { case A_CR0: - s->cr[0] =3D data; - s->cr0ack =3D data & ~SMMU_CR0_RESERVED; + bank->cr[0] =3D data; + bank->cr0ack =3D data & ~SMMU_CR0_RESERVED; /* in case the command queue has been enabled */ smmuv3_cmdq_consume(s); return MEMTX_OK; case A_CR1: - s->cr[1] =3D data; + bank->cr[1] =3D data; return MEMTX_OK; case A_CR2: - s->cr[2] =3D data; + bank->cr[2] =3D data; return MEMTX_OK; case A_IRQ_CTRL: - s->irq_ctrl =3D data; + bank->irq_ctrl =3D data; return MEMTX_OK; case A_GERRORN: smmuv3_write_gerrorn(s, data); @@ -1571,16 +1592,16 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, smmuv3_cmdq_consume(s); return MEMTX_OK; case A_GERROR_IRQ_CFG0: /* 64b */ - s->gerror_irq_cfg0 =3D deposit64(s->gerror_irq_cfg0, 0, 32, data); + bank->gerror_irq_cfg0 =3D deposit64(bank->gerror_irq_cfg0, 0, 32, = data); return MEMTX_OK; case A_GERROR_IRQ_CFG0 + 4: - s->gerror_irq_cfg0 =3D deposit64(s->gerror_irq_cfg0, 32, 32, data); + bank->gerror_irq_cfg0 =3D deposit64(bank->gerror_irq_cfg0, 32, 32,= data); return MEMTX_OK; case A_GERROR_IRQ_CFG1: - s->gerror_irq_cfg1 =3D data; + bank->gerror_irq_cfg1 =3D data; return MEMTX_OK; case A_GERROR_IRQ_CFG2: - s->gerror_irq_cfg2 =3D data; + bank->gerror_irq_cfg2 =3D data; return MEMTX_OK; case A_GBPA: /* @@ -1589,66 +1610,66 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, */ if (data & R_GBPA_UPDATE_MASK) { /* Ignore update bit as write is synchronous. */ - s->gbpa =3D data & ~R_GBPA_UPDATE_MASK; + bank->gbpa =3D data & ~R_GBPA_UPDATE_MASK; } return MEMTX_OK; case A_STRTAB_BASE: /* 64b */ - s->strtab_base =3D deposit64(s->strtab_base, 0, 32, data); + bank->strtab_base =3D deposit64(bank->strtab_base, 0, 32, data); return MEMTX_OK; case A_STRTAB_BASE + 4: - s->strtab_base =3D deposit64(s->strtab_base, 32, 32, data); + bank->strtab_base =3D deposit64(bank->strtab_base, 32, 32, data); return MEMTX_OK; case A_STRTAB_BASE_CFG: - s->strtab_base_cfg =3D data; + bank->strtab_base_cfg =3D data; if (FIELD_EX32(data, STRTAB_BASE_CFG, FMT) =3D=3D 1) { - s->sid_split =3D FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT); - s->features |=3D SMMU_FEATURE_2LVL_STE; + bank->sid_split =3D FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT); + bank->features |=3D SMMU_FEATURE_2LVL_STE; } return MEMTX_OK; case A_CMDQ_BASE: /* 64b */ - s->cmdq.base =3D deposit64(s->cmdq.base, 0, 32, data); - s->cmdq.log2size =3D extract64(s->cmdq.base, 0, 5); - if (s->cmdq.log2size > SMMU_CMDQS) { - s->cmdq.log2size =3D SMMU_CMDQS; + bank->cmdq.base =3D deposit64(bank->cmdq.base, 0, 32, data); + bank->cmdq.log2size =3D extract64(bank->cmdq.base, 0, 5); + if (bank->cmdq.log2size > SMMU_CMDQS) { + bank->cmdq.log2size =3D SMMU_CMDQS; } return MEMTX_OK; case A_CMDQ_BASE + 4: /* 64b */ - s->cmdq.base =3D deposit64(s->cmdq.base, 32, 32, data); + bank->cmdq.base =3D deposit64(bank->cmdq.base, 32, 32, data); return MEMTX_OK; case A_CMDQ_PROD: - s->cmdq.prod =3D data; + bank->cmdq.prod =3D data; smmuv3_cmdq_consume(s); return MEMTX_OK; case A_CMDQ_CONS: - s->cmdq.cons =3D data; + bank->cmdq.cons =3D data; return MEMTX_OK; case A_EVENTQ_BASE: /* 64b */ - s->eventq.base =3D deposit64(s->eventq.base, 0, 32, data); - s->eventq.log2size =3D extract64(s->eventq.base, 0, 5); - if (s->eventq.log2size > SMMU_EVENTQS) { - s->eventq.log2size =3D SMMU_EVENTQS; + bank->eventq.base =3D deposit64(bank->eventq.base, 0, 32, data); + bank->eventq.log2size =3D extract64(bank->eventq.base, 0, 5); + if (bank->eventq.log2size > SMMU_EVENTQS) { + bank->eventq.log2size =3D SMMU_EVENTQS; } return MEMTX_OK; case A_EVENTQ_BASE + 4: - s->eventq.base =3D deposit64(s->eventq.base, 32, 32, data); + bank->eventq.base =3D deposit64(bank->eventq.base, 32, 32, data); return MEMTX_OK; case A_EVENTQ_PROD: - s->eventq.prod =3D data; + bank->eventq.prod =3D data; return MEMTX_OK; case A_EVENTQ_CONS: - s->eventq.cons =3D data; + bank->eventq.cons =3D data; return MEMTX_OK; case A_EVENTQ_IRQ_CFG0: /* 64b */ - s->eventq_irq_cfg0 =3D deposit64(s->eventq_irq_cfg0, 0, 32, data); + bank->eventq_irq_cfg0 =3D deposit64(bank->eventq_irq_cfg0, 0, 32, = data); return MEMTX_OK; case A_EVENTQ_IRQ_CFG0 + 4: - s->eventq_irq_cfg0 =3D deposit64(s->eventq_irq_cfg0, 32, 32, data); + bank->eventq_irq_cfg0 =3D deposit64(bank->eventq_irq_cfg0, 32, 32,= data); return MEMTX_OK; case A_EVENTQ_IRQ_CFG1: - s->eventq_irq_cfg1 =3D data; + bank->eventq_irq_cfg1 =3D data; return MEMTX_OK; case A_EVENTQ_IRQ_CFG2: - s->eventq_irq_cfg2 =3D data; + bank->eventq_irq_cfg2 =3D data; return MEMTX_OK; default: qemu_log_mask(LOG_UNIMP, @@ -1687,18 +1708,21 @@ static MemTxResult smmu_write_mmio(void *opaque, hw= addr offset, uint64_t data, static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset, uint64_t *data, MemTxAttrs attrs) { + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + switch (offset) { case A_GERROR_IRQ_CFG0: - *data =3D s->gerror_irq_cfg0; + *data =3D bank->gerror_irq_cfg0; return MEMTX_OK; case A_STRTAB_BASE: - *data =3D s->strtab_base; + *data =3D bank->strtab_base; return MEMTX_OK; case A_CMDQ_BASE: - *data =3D s->cmdq.base; + *data =3D bank->cmdq.base; return MEMTX_OK; case A_EVENTQ_BASE: - *data =3D s->eventq.base; + *data =3D bank->eventq.base; return MEMTX_OK; default: *data =3D 0; @@ -1712,12 +1736,15 @@ static MemTxResult smmu_readll(SMMUv3State *s, hwad= dr offset, static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset, uint64_t *data, MemTxAttrs attrs) { + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + switch (offset) { case A_IDREGS ... A_IDREGS + 0x2f: *data =3D smmuv3_idreg(offset - A_IDREGS); return MEMTX_OK; case A_IDR0 ... A_IDR5: - *data =3D s->idr[(offset - A_IDR0) / 4]; + *data =3D bank->idr[(offset - A_IDR0) / 4]; return MEMTX_OK; case A_IIDR: *data =3D s->iidr; @@ -1726,77 +1753,77 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwadd= r offset, *data =3D s->aidr; return MEMTX_OK; case A_CR0: - *data =3D s->cr[0]; + *data =3D bank->cr[0]; return MEMTX_OK; case A_CR0ACK: - *data =3D s->cr0ack; + *data =3D bank->cr0ack; return MEMTX_OK; case A_CR1: - *data =3D s->cr[1]; + *data =3D bank->cr[1]; return MEMTX_OK; case A_CR2: - *data =3D s->cr[2]; + *data =3D bank->cr[2]; return MEMTX_OK; case A_STATUSR: *data =3D s->statusr; return MEMTX_OK; case A_GBPA: - *data =3D s->gbpa; + *data =3D bank->gbpa; return MEMTX_OK; case A_IRQ_CTRL: case A_IRQ_CTRL_ACK: - *data =3D s->irq_ctrl; + *data =3D bank->irq_ctrl; return MEMTX_OK; case A_GERROR: - *data =3D s->gerror; + *data =3D bank->gerror; return MEMTX_OK; case A_GERRORN: - *data =3D s->gerrorn; + *data =3D bank->gerrorn; return MEMTX_OK; case A_GERROR_IRQ_CFG0: /* 64b */ - *data =3D extract64(s->gerror_irq_cfg0, 0, 32); + *data =3D extract64(bank->gerror_irq_cfg0, 0, 32); return MEMTX_OK; case A_GERROR_IRQ_CFG0 + 4: - *data =3D extract64(s->gerror_irq_cfg0, 32, 32); + *data =3D extract64(bank->gerror_irq_cfg0, 32, 32); return MEMTX_OK; case A_GERROR_IRQ_CFG1: - *data =3D s->gerror_irq_cfg1; + *data =3D bank->gerror_irq_cfg1; return MEMTX_OK; case A_GERROR_IRQ_CFG2: - *data =3D s->gerror_irq_cfg2; + *data =3D bank->gerror_irq_cfg2; return MEMTX_OK; case A_STRTAB_BASE: /* 64b */ - *data =3D extract64(s->strtab_base, 0, 32); + *data =3D extract64(bank->strtab_base, 0, 32); return MEMTX_OK; case A_STRTAB_BASE + 4: /* 64b */ - *data =3D extract64(s->strtab_base, 32, 32); + *data =3D extract64(bank->strtab_base, 32, 32); return MEMTX_OK; case A_STRTAB_BASE_CFG: - *data =3D s->strtab_base_cfg; + *data =3D bank->strtab_base_cfg; return MEMTX_OK; case A_CMDQ_BASE: /* 64b */ - *data =3D extract64(s->cmdq.base, 0, 32); + *data =3D extract64(bank->cmdq.base, 0, 32); return MEMTX_OK; case A_CMDQ_BASE + 4: - *data =3D extract64(s->cmdq.base, 32, 32); + *data =3D extract64(bank->cmdq.base, 32, 32); return MEMTX_OK; case A_CMDQ_PROD: - *data =3D s->cmdq.prod; + *data =3D bank->cmdq.prod; return MEMTX_OK; case A_CMDQ_CONS: - *data =3D s->cmdq.cons; + *data =3D bank->cmdq.cons; return MEMTX_OK; case A_EVENTQ_BASE: /* 64b */ - *data =3D extract64(s->eventq.base, 0, 32); + *data =3D extract64(bank->eventq.base, 0, 32); return MEMTX_OK; case A_EVENTQ_BASE + 4: /* 64b */ - *data =3D extract64(s->eventq.base, 32, 32); + *data =3D extract64(bank->eventq.base, 32, 32); return MEMTX_OK; case A_EVENTQ_PROD: - *data =3D s->eventq.prod; + *data =3D bank->eventq.prod; return MEMTX_OK; case A_EVENTQ_CONS: - *data =3D s->eventq.cons; + *data =3D bank->eventq.cons; return MEMTX_OK; default: *data =3D 0; @@ -1916,9 +1943,10 @@ static const VMStateDescription vmstate_smmuv3_queue= =3D { static bool smmuv3_gbpa_needed(void *opaque) { SMMUv3State *s =3D opaque; + SMMUv3RegBank *bank =3D smmuv3_bank_ns(s); =20 /* Only migrate GBPA if it has different reset value. */ - return s->gbpa !=3D SMMU_GBPA_RESET_VAL; + return bank->gbpa !=3D SMMU_GBPA_RESET_VAL; } =20 static const VMStateDescription vmstate_gbpa =3D { @@ -1927,7 +1955,7 @@ static const VMStateDescription vmstate_gbpa =3D { .minimum_version_id =3D 1, .needed =3D smmuv3_gbpa_needed, .fields =3D (const VMStateField[]) { - VMSTATE_UINT32(gbpa, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].gbpa, SMMUv3State), VMSTATE_END_OF_LIST() } }; @@ -1938,27 +1966,29 @@ static const VMStateDescription vmstate_smmuv3 =3D { .minimum_version_id =3D 1, .priority =3D MIG_PRI_IOMMU, .fields =3D (const VMStateField[]) { - VMSTATE_UINT32(features, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].features, SMMUv3State), VMSTATE_UINT8(sid_size, SMMUv3State), - VMSTATE_UINT8(sid_split, SMMUv3State), + VMSTATE_UINT8(bank[SMMU_SEC_SID_NS].sid_split, SMMUv3State), =20 - VMSTATE_UINT32_ARRAY(cr, SMMUv3State, 3), - VMSTATE_UINT32(cr0ack, SMMUv3State), + VMSTATE_UINT32_ARRAY(bank[SMMU_SEC_SID_NS].cr, SMMUv3State, 3), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].cr0ack, SMMUv3State), VMSTATE_UINT32(statusr, SMMUv3State), - VMSTATE_UINT32(irq_ctrl, SMMUv3State), - VMSTATE_UINT32(gerror, SMMUv3State), - VMSTATE_UINT32(gerrorn, SMMUv3State), - VMSTATE_UINT64(gerror_irq_cfg0, SMMUv3State), - VMSTATE_UINT32(gerror_irq_cfg1, SMMUv3State), - VMSTATE_UINT32(gerror_irq_cfg2, SMMUv3State), - VMSTATE_UINT64(strtab_base, SMMUv3State), - VMSTATE_UINT32(strtab_base_cfg, SMMUv3State), - VMSTATE_UINT64(eventq_irq_cfg0, SMMUv3State), - VMSTATE_UINT32(eventq_irq_cfg1, SMMUv3State), - VMSTATE_UINT32(eventq_irq_cfg2, SMMUv3State), - - VMSTATE_STRUCT(cmdq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQue= ue), - VMSTATE_STRUCT(eventq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQ= ueue), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].irq_ctrl, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].gerror, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].gerrorn, SMMUv3State), + VMSTATE_UINT64(bank[SMMU_SEC_SID_NS].gerror_irq_cfg0, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].gerror_irq_cfg1, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].gerror_irq_cfg2, SMMUv3State), + VMSTATE_UINT64(bank[SMMU_SEC_SID_NS].strtab_base, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].strtab_base_cfg, SMMUv3State), + VMSTATE_UINT64(bank[SMMU_SEC_SID_NS].eventq_irq_cfg0, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].eventq_irq_cfg1, SMMUv3State), + VMSTATE_UINT32(bank[SMMU_SEC_SID_NS].eventq_irq_cfg2, SMMUv3State), + + VMSTATE_STRUCT(bank[SMMU_SEC_SID_NS].cmdq, SMMUv3State, 0, + vmstate_smmuv3_queue, SMMUQueue), + VMSTATE_STRUCT(bank[SMMU_SEC_SID_NS].eventq, SMMUv3State, 0, + vmstate_smmuv3_queue, SMMUQueue), =20 VMSTATE_END_OF_LIST(), }, diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 80d0fecfde..2dd6cfa895 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -40,6 +40,12 @@ #define CACHED_ENTRY_TO_ADDR(ent, addr) ((ent)->entry.translated_addr= + \ ((addr) & (ent)->entry.addr_m= ask)) =20 +/* StreamID Security state */ +typedef enum SMMUSecSID { + SMMU_SEC_SID_NS =3D 0, + SMMU_SEC_SID_NUM, +} SMMUSecSID; + /* * Page table walk error types */ diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index d183a62766..e9012fcdb0 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -32,19 +32,13 @@ typedef struct SMMUQueue { uint8_t log2size; } SMMUQueue; =20 -struct SMMUv3State { - SMMUState smmu_state; - +typedef struct SMMUv3RegBank { uint32_t features; - uint8_t sid_size; uint8_t sid_split; =20 uint32_t idr[6]; - uint32_t iidr; - uint32_t aidr; uint32_t cr[3]; uint32_t cr0ack; - uint32_t statusr; uint32_t gbpa; uint32_t irq_ctrl; uint32_t gerror; @@ -58,7 +52,19 @@ struct SMMUv3State { uint32_t eventq_irq_cfg1; uint32_t eventq_irq_cfg2; =20 - SMMUQueue eventq, cmdq; + SMMUQueue eventq; + SMMUQueue cmdq; +} SMMUv3RegBank; + +struct SMMUv3State { + SMMUState smmu_state; + + uint8_t sid_size; + uint32_t iidr; + uint32_t aidr; + uint32_t statusr; + + SMMUv3RegBank bank[SMMU_SEC_SID_NUM]; =20 qemu_irq irq[4]; QemuMutex mutex; @@ -84,7 +90,19 @@ struct SMMUv3Class { #define TYPE_ARM_SMMUV3 "arm-smmuv3" OBJECT_DECLARE_TYPE(SMMUv3State, SMMUv3Class, ARM_SMMUV3) =20 -#define STAGE1_SUPPORTED(s) FIELD_EX32(s->idr[0], IDR0, S1P) -#define STAGE2_SUPPORTED(s) FIELD_EX32(s->idr[0], IDR0, S2P) +#define STAGE1_SUPPORTED(s) \ + FIELD_EX32((s)->bank[SMMU_SEC_SID_NS].idr[0], IDR0, S1P) +#define STAGE2_SUPPORTED(s) \ + FIELD_EX32((s)->bank[SMMU_SEC_SID_NS].idr[0], IDR0, S2P) + +static inline SMMUv3RegBank *smmuv3_bank(SMMUv3State *s, SMMUSecSID sec_si= d) +{ + return &s->bank[sec_sid]; +} + +static inline SMMUv3RegBank *smmuv3_bank_ns(SMMUv3State *s) +{ + return smmuv3_bank(s, SMMU_SEC_SID_NS); +} =20 #endif --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281738623818.7812990827707; Sun, 12 Oct 2025 08:08:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfo-0001l1-5K; Sun, 12 Oct 2025 11:07:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfR-0001eM-7R; Sun, 12 Oct 2025 11:07:25 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfL-0001cu-B0; Sun, 12 Oct 2025 11:07:24 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwDn7mIcxOtooU6gAA--.30S2; Sun, 12 Oct 2025 23:07:08 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S9; Sun, 12 Oct 2025 23:07:07 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 06/21] hw/arm/smmuv3: Thread SEC_SID through helper APIs Date: Sun, 12 Oct 2025 23:06:46 +0800 Message-Id: <20251012150701.4127034-7-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S9 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBXQAAss Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3XrWkurWkAry5XF45ZFWkZwb_yoW7Xry8pw 4DAFn5KryUKFySgFZrJ3y8C3W3Zw4fKFn8Gr15Ga93G3WUCr1UXrn5G345ta4DWry8Zan2 v3yfGa1ruw47ArJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281742527154100 Content-Type: text/plain; charset="utf-8" Extend the register and queue helper routines to accept an explicit SEC_SID argument instead of hard-coding the non-secure bank. All existing callers are updated to pass SMMU_SEC_SID_NS, so the behavior remains identical. This prepares the code for handling additional security state banks in the future. So Non-secure state is the only state bank supported for now. Signed-off-by: Tao Tang --- hw/arm/smmuv3-internal.h | 21 +++++++++------------ hw/arm/smmuv3.c | 15 ++++++++------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index 858bc206a2..af0e0b32b3 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -246,9 +246,8 @@ REG64(S_EVENTQ_IRQ_CFG0, 0x80b0) REG32(S_EVENTQ_IRQ_CFG1, 0x80b8) REG32(S_EVENTQ_IRQ_CFG2, 0x80bc) =20 -static inline int smmu_enabled(SMMUv3State *s) +static inline int smmu_enabled(SMMUv3State *s, SMMUSecSID sec_sid) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); return FIELD_EX32(bank->cr[0], CR0, SMMUEN); } @@ -276,16 +275,16 @@ static inline uint32_t smmuv3_idreg(int regoffset) return smmuv3_ids[regoffset / 4]; } =20 -static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s) +static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s, + SMMUSecSID sec_sid) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); return FIELD_EX32(bank->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN); } =20 -static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s) +static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s, + SMMUSecSID sec_sid) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); return FIELD_EX32(bank->irq_ctrl, IRQ_CTRL, GERROR_IRQEN); } @@ -330,23 +329,21 @@ static inline void queue_cons_incr(SMMUQueue *q) q->cons =3D deposit32(q->cons, 0, q->log2size + 1, q->cons + 1); } =20 -static inline bool smmuv3_cmdq_enabled(SMMUv3State *s) +static inline bool smmuv3_cmdq_enabled(SMMUv3State *s, SMMUSecSID sec_sid) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); return FIELD_EX32(bank->cr[0], CR0, CMDQEN); } =20 -static inline bool smmuv3_eventq_enabled(SMMUv3State *s) +static inline bool smmuv3_eventq_enabled(SMMUv3State *s, SMMUSecSID sec_si= d) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); return FIELD_EX32(bank->cr[0], CR0, EVENTQEN); } =20 -static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type) +static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type, + SMMUSecSID sec_sid) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); bank->cmdq.cons =3D FIELD_DP32(bank->cmdq.cons, CMDQ_CONS, ERR, err_ty= pe); } diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 9c085ac678..6d05bb1310 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -57,7 +57,7 @@ static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq ir= q, =20 switch (irq) { case SMMU_IRQ_EVTQ: - pulse =3D smmuv3_eventq_irq_enabled(s); + pulse =3D smmuv3_eventq_irq_enabled(s, sec_sid); break; case SMMU_IRQ_PRIQ: qemu_log_mask(LOG_UNIMP, "PRI not yet supported\n"); @@ -77,7 +77,7 @@ static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq ir= q, bank->gerror ^=3D new_gerrors; trace_smmuv3_write_gerror(new_gerrors, bank->gerror); =20 - pulse =3D smmuv3_gerror_irq_enabled(s); + pulse =3D smmuv3_gerror_irq_enabled(s, sec_sid); break; } } @@ -153,7 +153,7 @@ static MemTxResult smmuv3_write_eventq(SMMUv3State *s, = Evt *evt) SMMUQueue *q =3D &bank->eventq; MemTxResult r; =20 - if (!smmuv3_eventq_enabled(s)) { + if (!smmuv3_eventq_enabled(s, sec_sid)) { return MEMTX_ERROR; } =20 @@ -176,8 +176,9 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo = *info) { Evt evt =3D {}; MemTxResult r; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; =20 - if (!smmuv3_eventq_enabled(s)) { + if (!smmuv3_eventq_enabled(s, sec_sid)) { return; } =20 @@ -1070,7 +1071,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegi= on *mr, hwaddr addr, =20 qemu_mutex_lock(&s->mutex); =20 - if (!smmu_enabled(s)) { + if (!smmu_enabled(s, sec_sid)) { if (FIELD_EX32(bank->gbpa, GBPA, ABORT)) { status =3D SMMU_TRANS_ABORT; } else { @@ -1300,7 +1301,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) SMMUQueue *q =3D &bank->cmdq; SMMUCommandType type =3D 0; =20 - if (!smmuv3_cmdq_enabled(s)) { + if (!smmuv3_cmdq_enabled(s, sec_sid)) { return 0; } /* @@ -1513,7 +1514,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) =20 if (cmd_error) { trace_smmuv3_cmdq_consume_error(smmu_cmd_string(type), cmd_error); - smmu_write_cmdq_err(s, cmd_error); + smmu_write_cmdq_err(s, cmd_error, sec_sid); smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_CMDQ_ERR_MASK); } =20 --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281784864196.47435955882895; Sun, 12 Oct 2025 08:09:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfm-0001kY-Nt; Sun, 12 Oct 2025 11:07:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfR-0001eA-2I; Sun, 12 Oct 2025 11:07:25 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfL-0001cp-Am; Sun, 12 Oct 2025 11:07:24 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwD31yQexOtocicrAA--.35250S2; Sun, 12 Oct 2025 23:07:10 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S10; Sun, 12 Oct 2025 23:07:08 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 07/21] hw/arm/smmuv3: Track SEC_SID in configs and events Date: Sun, 12 Oct 2025 23:06:47 +0800 Message-Id: <20251012150701.4127034-8-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S10 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBYAAAsR Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3XrWkuF45tw1fAF18XrW3Awb_yoW7AFW7pw 1DGrn8Krn5ta4SvFy3XF4UZa13J3ykKrn8Kr9Fgr95Aws5urW7XF4DGa45ur98uryrtrW2 v3yIgFW5uFyjv3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281789303158500 Content-Type: text/plain; charset="utf-8" Cache the SEC_SID inside SMMUTransCfg to keep configuration lookups tied to the correct register bank. Plumb the SEC_SID through tracepoints and queue helpers so diagnostics and event logs always show which security interface emitted the record. To support this, the SEC_SID is placed in SMMUEventInfo so the bank is identified as soon as an event record is built. Signed-off-by: Tao Tang --- hw/arm/smmuv3-internal.h | 1 + hw/arm/smmuv3.c | 22 +++++++++++++++------- hw/arm/trace-events | 2 +- include/hw/arm/smmu-common.h | 1 + 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index af0e0b32b3..99fdbcf3f5 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -512,6 +512,7 @@ static inline const char *smmu_event_string(SMMUEventTy= pe type) =20 /* Encode an event record */ typedef struct SMMUEventInfo { + SMMUSecSID sec_sid; SMMUEventType type; uint32_t sid; bool recorded; diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 6d05bb1310..a87ae36e8b 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -146,9 +146,9 @@ static MemTxResult queue_write(SMMUQueue *q, Evt *evt_i= n) return MEMTX_OK; } =20 -static MemTxResult smmuv3_write_eventq(SMMUv3State *s, Evt *evt) +static MemTxResult smmuv3_write_eventq(SMMUv3State *s, SMMUSecSID sec_sid, + Evt *evt) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); SMMUQueue *q =3D &bank->eventq; MemTxResult r; @@ -176,7 +176,10 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo= *info) { Evt evt =3D {}; MemTxResult r; - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUSecSID sec_sid =3D info->sec_sid; + if (sec_sid >=3D SMMU_SEC_SID_NUM) { + g_assert_not_reached(); + } =20 if (!smmuv3_eventq_enabled(s, sec_sid)) { return; @@ -256,8 +259,9 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo = *info) g_assert_not_reached(); } =20 - trace_smmuv3_record_event(smmu_event_string(info->type), info->sid); - r =3D smmuv3_write_eventq(s, &evt); + trace_smmuv3_record_event(sec_sid, smmu_event_string(info->type), + info->sid); + r =3D smmuv3_write_eventq(s, sec_sid, &evt); if (r !=3D MEMTX_OK) { smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MAS= K); } @@ -900,6 +904,7 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev= , SMMUEventInfo *event) 100 * sdev->cfg_cache_hits / (sdev->cfg_cache_hits + sdev->cfg_cache_misses= )); cfg =3D g_new0(SMMUTransCfg, 1); + cfg->sec_sid =3D SMMU_SEC_SID_NS; =20 if (!smmuv3_decode_config(&sdev->iommu, cfg, event)) { g_hash_table_insert(bc->configs, sdev, cfg); @@ -1057,7 +1062,8 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegi= on *mr, hwaddr addr, SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); SMMUEventInfo event =3D {.type =3D SMMU_EVT_NONE, .sid =3D sid, - .inval_ste_allowed =3D false}; + .inval_ste_allowed =3D false, + .sec_sid =3D sec_sid}; SMMUTranslationStatus status; SMMUTransCfg *cfg =3D NULL; IOMMUTLBEntry entry =3D { @@ -1159,7 +1165,9 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, uint64_t num_pages, int stage) { SMMUDevice *sdev =3D container_of(mr, SMMUDevice, iommu); - SMMUEventInfo eventinfo =3D {.inval_ste_allowed =3D true}; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUEventInfo eventinfo =3D {.sec_sid =3D sec_sid, + .inval_ste_allowed =3D true}; SMMUTransCfg *cfg =3D smmuv3_get_config(sdev, &eventinfo); IOMMUTLBEvent event; uint8_t granule; diff --git a/hw/arm/trace-events b/hw/arm/trace-events index f3386bd7ae..96ebd1b11b 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -40,7 +40,7 @@ smmuv3_cmdq_opcode(const char *opcode) "<--- %s" smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, u= int8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d " smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error = on %s command execution: %d" smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) = "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)" -smmuv3_record_event(const char *type, uint32_t sid) "%s sid=3D0x%x" +smmuv3_record_event(int sec_sid, const char *type, uint32_t sid) "sec_sid= =3D%d %s sid=3D0x%x" smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "sid= =3D0x%x features:0x%x, sid_split:0x%x" smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offs= et, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%"PRI= x64" l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_st= e:%d" smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64 diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 2dd6cfa895..b0dae18a62 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -107,6 +107,7 @@ typedef struct SMMUS2Cfg { typedef struct SMMUTransCfg { /* Shared fields between stage-1 and stage-2. */ SMMUStage stage; /* translation stage */ + SMMUSecSID sec_sid; /* cached sec sid */ bool disabled; /* smmu is disabled */ bool bypassed; /* translation is bypassed */ bool aborted; /* translation is aborted */ --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281712084825.2954061012827; Sun, 12 Oct 2025 08:08:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfU-0001fo-4V; Sun, 12 Oct 2025 11:07:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfN-0001aw-Qy; Sun, 12 Oct 2025 11:07:21 -0400 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfK-0001d8-MT; Sun, 12 Oct 2025 11:07:21 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwB3WCUexOtobicrAA--.7763S2; Sun, 12 Oct 2025 23:07:10 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S11; Sun, 12 Oct 2025 23:07:09 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 08/21] hw/arm/smmuv3: Add separate address space for secure SMMU accesses Date: Sun, 12 Oct 2025 23:06:48 +0800 Message-Id: <20251012150701.4127034-9-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S11 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBYAABsQ Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxWr4xXrykCw1DCr43Xw4UCFg_yoW5KFW7pa 9rArZxt390k3W2yrZ3Xrnrua4rWa95WF4UKrsFk3s5uF13Kr13Ar4qk3WUGF9rCr45Ja12 vF17Zr4fWF1jqrJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=209.97.181.73; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281720852158500 Content-Type: text/plain; charset="utf-8" According to the Arm architecture, SMMU-originated memory accesses, such as fetching commands or writing events for a secure stream, must target the Secure Physical Address (PA) space. The existing model sends all DMA to the global non-secure address_space_memory. This patch introduces the infrastructure to differentiate between secure and non-secure memory accesses. Firstly, SMMU_SEC_SID_S is added in SMMUSecSID enum to represent the secure context. Then a weak global symbol, arm_secure_address_space, is added, which can be provided by the machine model to represent the Secure PA space. A new helper, smmu_get_address_space(), selects the target address space based on SEC_SID. All internal DMA calls (dma_memory_read/write) will be updated to use this helper in follow-up patches. Signed-off-by: Tao Tang --- hw/arm/smmu-common.c | 8 ++++++++ hw/arm/virt.c | 5 +++++ include/hw/arm/smmu-common.h | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 62a7612184..24db448683 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -30,6 +30,14 @@ #include "hw/arm/smmu-common.h" #include "smmu-internal.h" =20 +/* Global state for secure address space availability */ +bool arm_secure_as_available; + +void smmu_enable_secure_address_space(void) +{ + arm_secure_as_available =3D true; +} + /* IOTLB Management */ =20 static guint smmu_iotlb_key_hash(gconstpointer v) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 175023897a..83dc62a095 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -92,6 +92,8 @@ #include "hw/cxl/cxl_host.h" #include "qemu/guest-random.h" =20 +AddressSpace arm_secure_address_space; + static GlobalProperty arm_virt_compat[] =3D { { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" }, }; @@ -2257,6 +2259,9 @@ static void machvirt_init(MachineState *machine) memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory", UINT64_MAX); memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1); + address_space_init(&arm_secure_address_space, secure_sysmem, + "secure-memory-space"); + smmu_enable_secure_address_space(); } =20 firmware_loaded =3D virt_firmware_init(vms, sysmem, diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index b0dae18a62..d54558f94b 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -43,9 +43,36 @@ /* StreamID Security state */ typedef enum SMMUSecSID { SMMU_SEC_SID_NS =3D 0, + SMMU_SEC_SID_S, SMMU_SEC_SID_NUM, } SMMUSecSID; =20 +extern AddressSpace __attribute__((weak)) arm_secure_address_space; +extern bool arm_secure_as_available; +void smmu_enable_secure_address_space(void); + +/* + * Return the address space corresponding to the SEC_SID. + * If SEC_SID is Secure, but secure address space is not available, + * return NULL and print a warning message. + */ +static inline AddressSpace *smmu_get_address_space(SMMUSecSID sec_sid) +{ + switch (sec_sid) { + case SMMU_SEC_SID_NS: + return &address_space_memory; + case SMMU_SEC_SID_S: + if (!arm_secure_as_available || arm_secure_address_space.root =3D= =3D NULL) { + printf("Secure address space requested but not available"); + return NULL; + } + return &arm_secure_address_space; + default: + printf("Unknown SEC_SID value %d", sec_sid); + return NULL; + } +} + /* * Page table walk error types */ --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281714830393.5964175330241; Sun, 12 Oct 2025 08:08:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfU-0001fM-2j; Sun, 12 Oct 2025 11:07:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfP-0001cG-C7; Sun, 12 Oct 2025 11:07:23 -0400 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfL-0001cq-5T; Sun, 12 Oct 2025 11:07:23 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwA3GGAexOtorE6gAA--.61S2; Sun, 12 Oct 2025 23:07:10 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S12; Sun, 12 Oct 2025 23:07:09 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 09/21] hw/arm/smmuv3: Plumb transaction attributes into config helpers Date: Sun, 12 Oct 2025 23:06:49 +0800 Message-Id: <20251012150701.4127034-10-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S12 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBYAACsT Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxKw1DJFWDuw4UXr4rury8Zrb_yoW3AFWUpa nrGFn8tw4rtFyfZFZxXr4q93W3J3yvgFn8Gry29F9Ykr13Ar17Zr4DK345GryDZry8JFsr ZFyIgF45ZrnrA3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=209.97.181.73; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281720980154100 Content-Type: text/plain; charset="utf-8" As a preliminary step towards a multi-security-state configuration cache, introduce MemTxAttrs and AddressSpace * members to the SMMUTransCfg struct. The goal is to cache these attributes so that internal DMA calls (dma_memory_read/write) can use them directly. To facilitate this, hw/arm/arm-security.h is now included in smmu-common.h. This is a notable change, as it marks the first time these Arm CPU-specific security space definitions are used outside of cpu.h, making them more generally available for device models. The decode helpers (smmu_get_ste, smmu_get_cd, smmu_find_ste, smmuv3_get_config) are updated to use these new attributes for memory accesses. This ensures that reads of SMMU structures from memory, such as the Stream Table, use the correct security context. For now, the configuration cache lookup key remains unchanged and is still based solely on the SMMUDevice pointer. The new attributes are populated during a cache miss in smmuv3_get_config. Signed-off-by: Tao Tang --- hw/arm/smmu-common.c | 19 ++++++++++++++++++ hw/arm/smmuv3.c | 38 ++++++++++++++++++++++-------------- include/hw/arm/smmu-common.h | 6 ++++++ 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 24db448683..82308f0e33 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -30,6 +30,25 @@ #include "hw/arm/smmu-common.h" #include "smmu-internal.h" =20 +ARMSecuritySpace smmu_get_security_space(SMMUSecSID sec_sid) +{ + switch (sec_sid) { + case SMMU_SEC_SID_S: + return ARMSS_Secure; + case SMMU_SEC_SID_NS: + default: + return ARMSS_NonSecure; + } +} + +MemTxAttrs smmu_get_txattrs(SMMUSecSID sec_sid) +{ + return (MemTxAttrs) { + .secure =3D sec_sid > SMMU_SEC_SID_NS ? 1 : 0, + .space =3D smmu_get_security_space(sec_sid), + }; +} + /* Global state for secure address space availability */ bool arm_secure_as_available; =20 diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index a87ae36e8b..351bbf1ae9 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -333,14 +333,13 @@ static void smmuv3_init_regs(SMMUv3State *s) } =20 static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, - SMMUEventInfo *event) + SMMUEventInfo *event, SMMUTransCfg *cfg) { int ret, i; =20 trace_smmuv3_get_ste(addr); /* TODO: guarantee 64-bit single-copy atomicity */ - ret =3D dma_memory_read(&address_space_memory, addr, buf, sizeof(*buf), - MEMTXATTRS_UNSPECIFIED); + ret =3D dma_memory_read(cfg->as, addr, buf, sizeof(*buf), cfg->txattrs= ); if (ret !=3D MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "Cannot fetch pte at address=3D0x%"PRIx64"\n", addr); @@ -385,8 +384,7 @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, SMMUTr= ansCfg *cfg, } =20 /* TODO: guarantee 64-bit single-copy atomicity */ - ret =3D dma_memory_read(&address_space_memory, addr, buf, sizeof(*buf), - MEMTXATTRS_UNSPECIFIED); + ret =3D dma_memory_read(cfg->as, addr, buf, sizeof(*buf), cfg->txattrs= ); if (ret !=3D MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "Cannot fetch pte at address=3D0x%"PRIx64"\n", addr); @@ -639,18 +637,19 @@ bad_ste: * @sid: stream ID * @ste: returned stream table entry * @event: handle to an event info + * @cfg: translation configuration cache * * Supports linear and 2-level stream table * Return 0 on success, -EINVAL otherwise */ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, - SMMUEventInfo *event) + SMMUEventInfo *event, SMMUTransCfg *cfg) { dma_addr_t addr, strtab_base; uint32_t log2size; int strtab_size_shift; int ret; - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUSecSID sec_sid =3D cfg->sec_sid; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); =20 trace_smmuv3_find_ste(sid, bank->features, bank->sid_split); @@ -678,8 +677,8 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, = STE *ste, l2_ste_offset =3D sid & ((1 << bank->sid_split) - 1); l1ptr =3D (dma_addr_t)(strtab_base + l1_ste_offset * sizeof(l1std)= ); /* TODO: guarantee 64-bit single-copy atomicity */ - ret =3D dma_memory_read(&address_space_memory, l1ptr, &l1std, - sizeof(l1std), MEMTXATTRS_UNSPECIFIED); + ret =3D dma_memory_read(cfg->as, l1ptr, &l1std, sizeof(l1std), + cfg->txattrs); if (ret !=3D MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "Could not read L1PTR at 0X%"PRIx64"\n", l1ptr); @@ -721,7 +720,7 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, = STE *ste, addr =3D strtab_base + sid * sizeof(*ste); } =20 - if (smmu_get_ste(s, addr, ste, event)) { + if (smmu_get_ste(s, addr, ste, event, cfg)) { return -EINVAL; } =20 @@ -850,7 +849,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, = SMMUTransCfg *cfg, /* ASID defaults to -1 (if s1 is not supported). */ cfg->asid =3D -1; =20 - ret =3D smmu_find_ste(s, sid, &ste, event); + ret =3D smmu_find_ste(s, sid, &ste, event, cfg); if (ret) { return ret; } @@ -884,7 +883,8 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, = SMMUTransCfg *cfg, * decoding under the form of an SMMUTransCfg struct. The hash table is in= dexed * by the SMMUDevice handle. */ -static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev, SMMUEventInfo *ev= ent) +static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev, SMMUEventInfo *ev= ent, + SMMUSecSID sec_sid) { SMMUv3State *s =3D sdev->smmu; SMMUState *bc =3D &s->smmu_state; @@ -904,7 +904,15 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sde= v, SMMUEventInfo *event) 100 * sdev->cfg_cache_hits / (sdev->cfg_cache_hits + sdev->cfg_cache_misses= )); cfg =3D g_new0(SMMUTransCfg, 1); - cfg->sec_sid =3D SMMU_SEC_SID_NS; + cfg->sec_sid =3D sec_sid; + cfg->txattrs =3D smmu_get_txattrs(sec_sid); + cfg->as =3D smmu_get_address_space(sec_sid); + if (!cfg->as) { + /* Can't get AddressSpace, free cfg and return. */ + g_free(cfg); + cfg =3D NULL; + return cfg; + } =20 if (!smmuv3_decode_config(&sdev->iommu, cfg, event)) { g_hash_table_insert(bc->configs, sdev, cfg); @@ -1086,7 +1094,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegi= on *mr, hwaddr addr, goto epilogue; } =20 - cfg =3D smmuv3_get_config(sdev, &event); + cfg =3D smmuv3_get_config(sdev, &event, sec_sid); if (!cfg) { status =3D SMMU_TRANS_ERROR; goto epilogue; @@ -1168,7 +1176,7 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUEventInfo eventinfo =3D {.sec_sid =3D sec_sid, .inval_ste_allowed =3D true}; - SMMUTransCfg *cfg =3D smmuv3_get_config(sdev, &eventinfo); + SMMUTransCfg *cfg =3D smmuv3_get_config(sdev, &eventinfo, sec_sid); IOMMUTLBEvent event; uint8_t granule; =20 diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index d54558f94b..c17c7db6e5 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -22,6 +22,7 @@ #include "hw/sysbus.h" #include "hw/pci/pci.h" #include "qom/object.h" +#include "hw/arm/arm-security.h" =20 #define SMMU_PCI_BUS_MAX 256 #define SMMU_PCI_DEVFN_MAX 256 @@ -47,6 +48,9 @@ typedef enum SMMUSecSID { SMMU_SEC_SID_NUM, } SMMUSecSID; =20 +MemTxAttrs smmu_get_txattrs(SMMUSecSID sec_sid); +ARMSecuritySpace smmu_get_security_space(SMMUSecSID sec_sid); + extern AddressSpace __attribute__((weak)) arm_secure_address_space; extern bool arm_secure_as_available; void smmu_enable_secure_address_space(void); @@ -150,6 +154,8 @@ typedef struct SMMUTransCfg { SMMUTransTableInfo tt[2]; /* Used by stage-2 only. */ struct SMMUS2Cfg s2cfg; + MemTxAttrs txattrs; /* cached transaction attributes */ + AddressSpace *as; /* cached address space */ } SMMUTransCfg; =20 typedef struct SMMUDevice { --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281761282926.8705299780287; Sun, 12 Oct 2025 08:09:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfh-0001ic-6o; Sun, 12 Oct 2025 11:07:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfS-0001ff-Pp; Sun, 12 Oct 2025 11:07:27 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfN-0001cs-Rt; Sun, 12 Oct 2025 11:07:26 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwDn75sfxOtouE6gAA--.5S2; Sun, 12 Oct 2025 23:07:11 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S13; Sun, 12 Oct 2025 23:07:10 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 10/21] hw/arm/smmu-common: Key configuration cache on SMMUDevice and SEC_SID Date: Sun, 12 Oct 2025 23:06:50 +0800 Message-Id: <20251012150701.4127034-11-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S13 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBZAAAsV Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxKFW7GFWUZw47Zr4xXFWUArb_yoWxCw1kpr W8JF98Jr4UGF1fGFsxXFWI93Z8Wwn29r1fGryagr9YyFyqyryUAF4DK3yYk3s3CrW8JF47 ZaySgFyUCr17JaDanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281762067154100 Content-Type: text/plain; charset="utf-8" Adapt the configuration cache to support multiple security states by introducing a composite key, SMMUConfigKey. This key combines the SMMUDevice with SEC_SID, preventing aliasing between Secure and Non-secure configurations for the same device, also the future Realm and Root configurations. The cache lookup, insertion, and invalidation mechanisms are updated to use this new keying infrastructure. This change is critical for ensuring correct translation when a device is active in more than one security world. Signed-off-by: Tao Tang --- hw/arm/smmu-common.c | 45 ++++++++++++++++++++++++++++++++++-- hw/arm/smmuv3.c | 13 +++++++---- include/hw/arm/smmu-common.h | 7 ++++++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 82308f0e33..5fabe30c75 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -30,6 +30,26 @@ #include "hw/arm/smmu-common.h" #include "smmu-internal.h" =20 +/* Configuration Cache Management */ +static guint smmu_config_key_hash(gconstpointer key) +{ + const SMMUConfigKey *k =3D key; + return g_direct_hash(k->sdev) ^ (guint)k->sec_sid; +} + +static gboolean smmu_config_key_equal(gconstpointer a, gconstpointer b) +{ + const SMMUConfigKey *ka =3D a; + const SMMUConfigKey *kb =3D b; + return ka->sdev =3D=3D kb->sdev && ka->sec_sid =3D=3D kb->sec_sid; +} + +SMMUConfigKey smmu_get_config_key(SMMUDevice *sdev, SMMUSecSID sec_sid) +{ + SMMUConfigKey key =3D {.sdev =3D sdev, .sec_sid =3D sec_sid}; + return key; +} + ARMSecuritySpace smmu_get_security_space(SMMUSecSID sec_sid) { switch (sec_sid) { @@ -256,7 +276,8 @@ static gboolean smmu_hash_remove_by_vmid_ipa(gpointer k= ey, gpointer value, static gboolean smmu_hash_remove_by_sid_range(gpointer key, gpointer value, gpointer user_= data) { - SMMUDevice *sdev =3D (SMMUDevice *)key; + SMMUConfigKey *config_key =3D (SMMUConfigKey *)key; + SMMUDevice *sdev =3D config_key->sdev; uint32_t sid =3D smmu_get_sid(sdev); SMMUSIDRange *sid_range =3D (SMMUSIDRange *)user_data; =20 @@ -274,6 +295,24 @@ void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDR= ange sid_range) &sid_range); } =20 +static gboolean smmu_hash_remove_by_sdev(gpointer key, gpointer value, + gpointer user_data) +{ + SMMUConfigKey *config_key =3D (SMMUConfigKey *)key; + SMMUDevice *target =3D (SMMUDevice *)user_data; + + if (config_key->sdev !=3D target) { + return false; + } + trace_smmu_config_cache_inv(smmu_get_sid(target)); + return true; +} + +void smmu_configs_inv_sdev(SMMUState *s, SMMUDevice *sdev) +{ + g_hash_table_foreach_remove(s->configs, smmu_hash_remove_by_sdev, sdev= ); +} + void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova, uint8_t tg, uint64_t num_pages, uint8_t ttl) { @@ -961,7 +1000,9 @@ static void smmu_base_realize(DeviceState *dev, Error = **errp) error_propagate(errp, local_err); return; } - s->configs =3D g_hash_table_new_full(NULL, NULL, NULL, g_free); + s->configs =3D g_hash_table_new_full(smmu_config_key_hash, + smmu_config_key_equal, + g_free, g_free); s->iotlb =3D g_hash_table_new_full(smmu_iotlb_key_hash, smmu_iotlb_key= _equal, g_free, g_free); s->smmu_pcibus_by_busptr =3D g_hash_table_new(NULL, NULL); diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 351bbf1ae9..55f4ad1757 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -878,10 +878,11 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr= , SMMUTransCfg *cfg, * * @sdev: SMMUDevice handle * @event: output event info + * @sec_sid: StreamID Security state * * The configuration cache contains data resulting from both STE and CD * decoding under the form of an SMMUTransCfg struct. The hash table is in= dexed - * by the SMMUDevice handle. + * by a composite key of the SMMUDevice and the sec_sid. */ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev, SMMUEventInfo *ev= ent, SMMUSecSID sec_sid) @@ -889,8 +890,9 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev= , SMMUEventInfo *event, SMMUv3State *s =3D sdev->smmu; SMMUState *bc =3D &s->smmu_state; SMMUTransCfg *cfg; + SMMUConfigKey lookup_key =3D smmu_get_config_key(sdev, sec_sid); =20 - cfg =3D g_hash_table_lookup(bc->configs, sdev); + cfg =3D g_hash_table_lookup(bc->configs, &lookup_key); if (cfg) { sdev->cfg_cache_hits++; trace_smmuv3_config_cache_hit(smmu_get_sid(sdev), @@ -915,7 +917,9 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev= , SMMUEventInfo *event, } =20 if (!smmuv3_decode_config(&sdev->iommu, cfg, event)) { - g_hash_table_insert(bc->configs, sdev, cfg); + SMMUConfigKey *persistent_key =3D g_new(SMMUConfigKey, 1); + *persistent_key =3D lookup_key; + g_hash_table_insert(bc->configs, persistent_key, cfg); } else { g_free(cfg); cfg =3D NULL; @@ -929,8 +933,7 @@ static void smmuv3_flush_config(SMMUDevice *sdev) SMMUv3State *s =3D sdev->smmu; SMMUState *bc =3D &s->smmu_state; =20 - trace_smmu_config_cache_inv(smmu_get_sid(sdev)); - g_hash_table_remove(bc->configs, sdev); + smmu_configs_inv_sdev(bc, sdev); } =20 /* Do translation with TLB lookup. */ diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index c17c7db6e5..bccbbe0115 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -182,6 +182,11 @@ typedef struct SMMUIOTLBKey { uint8_t level; } SMMUIOTLBKey; =20 +typedef struct SMMUConfigKey { + SMMUDevice *sdev; + SMMUSecSID sec_sid; +} SMMUConfigKey; + typedef struct SMMUSIDRange { uint32_t start; uint32_t end; @@ -257,6 +262,7 @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTran= sCfg *cfg, void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *ent= ry); SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uint64_t iova, uint8_t tg, uint8_t level); +SMMUConfigKey smmu_get_config_key(SMMUDevice *sdev, SMMUSecSID sec_sid); void smmu_iotlb_inv_all(SMMUState *s); void smmu_iotlb_inv_asid_vmid(SMMUState *s, int asid, int vmid); void smmu_iotlb_inv_vmid(SMMUState *s, int vmid); @@ -266,6 +272,7 @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vm= id, dma_addr_t iova, void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_addr_t ipa, uint8_t tg, uint64_t num_pages, uint8_t ttl); void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range); +void smmu_configs_inv_sdev(SMMUState *s, SMMUDevice *sdev); /* Unmap the range of all the notifiers registered to any IOMMU mr */ void smmu_inv_notifiers_all(SMMUState *s); =20 --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281710998659.0303768453318; Sun, 12 Oct 2025 08:08:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfa-0001hN-91; Sun, 12 Oct 2025 11:07:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xfQ-0001e8-Pe; Sun, 12 Oct 2025 11:07:24 -0400 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xfL-0001cn-I7; Sun, 12 Oct 2025 11:07:24 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwDX31MfxOtodicrAA--.7514S2; Sun, 12 Oct 2025 23:07:11 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXPOoXxOto33dMAA--.3068S14; Sun, 12 Oct 2025 23:07:11 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 11/21] hw/arm/smmuv3: Decode security attributes from descriptors Date: Sun, 12 Oct 2025 23:06:51 +0800 Message-Id: <20251012150701.4127034-12-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXPOoXxOto33dMAA--.3068S14 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBZgAAsX Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxXrW7Ww43try5uryxWw1Dtrb_yoWrCw15pa 97Gr98KrW5G3WI93ykXr43uFsxXws5JF1UCr9Fgr95Ar4aqw17Xr1Ika45KF9FgrZ5Jr47 Zr4q9348urWjqrJanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=209.97.181.73; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281720865158500 Content-Type: text/plain; charset="utf-8" As the first step in implementing secure page table walks, this patch introduces the logic to decode security-related attributes from various SMMU structures. The NSCFG bits from the Context Descriptor are now decoded and stored. These bits control the security attribute of the starting-level translation table, which is crucial for managing secure and non-secure memory accesses. The SMMU_S_IDR1.SEL2 bit is read to determine if Secure stage 2 translations are supported. This capability is cached in the SMMUTransCfg structure for the page table walker's use. Finally, new macros (PTE_NS, PTE_NSTABLE) are added to prepare for extracting attributes from page and table descriptors. To improve clarity, these different attribute bits are organized into distinct subsections in the header file. Signed-off-by: Tao Tang --- hw/arm/smmu-internal.h | 16 ++++++++++++++-- hw/arm/smmuv3-internal.h | 2 ++ hw/arm/smmuv3.c | 2 ++ include/hw/arm/smmu-common.h | 3 +++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h index d143d296f3..a0454f720d 100644 --- a/hw/arm/smmu-internal.h +++ b/hw/arm/smmu-internal.h @@ -58,16 +58,28 @@ ((level =3D=3D 3) && = \ ((pte & ARM_LPAE_PTE_TYPE_MASK) =3D=3D ARM_LPAE_L3_PTE_TYPE_PAGE)) =20 +/* Block & page descriptor attributes */ +/* Non-secure bit */ +#define PTE_NS(pte) \ + (extract64(pte, 5, 1)) + /* access permissions */ =20 #define PTE_AP(pte) \ (extract64(pte, 6, 2)) =20 +/* access flag */ +#define PTE_AF(pte) \ + (extract64(pte, 10, 1)) + + +/* Table descriptor attributes */ #define PTE_APTABLE(pte) \ (extract64(pte, 61, 2)) =20 -#define PTE_AF(pte) \ - (extract64(pte, 10, 1)) +#define PTE_NSTABLE(pte) \ + (extract64(pte, 63, 1)) + /* * TODO: At the moment all transactions are considered as privileged (EL1) * as IOMMU translation callback does not pass user/priv attributes. diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index 99fdbcf3f5..1e757af459 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -703,6 +703,8 @@ static inline int oas2bits(int oas_field) #define CD_R(x) extract32((x)->word[1], 13, 1) #define CD_A(x) extract32((x)->word[1], 14, 1) #define CD_AARCH64(x) extract32((x)->word[1], 9 , 1) +#define CD_NSCFG0(x) extract32((x)->word[2], 0, 1) +#define CD_NSCFG1(x) extract32((x)->word[4], 0, 1) =20 /** * tg2granule - Decodes the CD translation granule size field according diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 55f4ad1757..3686056d8e 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -812,6 +812,7 @@ static int decode_cd(SMMUv3State *s, SMMUTransCfg *cfg, tt->ttb =3D CACHED_ENTRY_TO_ADDR(entry, tt->ttb); } =20 + tt->nscfg =3D i ? CD_NSCFG1(cd) : CD_NSCFG0(cd); tt->had =3D CD_HAD(cd, i); trace_smmuv3_decode_cd_tt(i, tt->tsz, tt->ttb, tt->granule_sz, tt-= >had); } @@ -915,6 +916,7 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev= , SMMUEventInfo *event, cfg =3D NULL; return cfg; } + cfg->sel2 =3D FIELD_EX32(s->bank[SMMU_SEC_SID_S].idr[1], S_IDR1, S= EL2); =20 if (!smmuv3_decode_config(&sdev->iommu, cfg, event)) { SMMUConfigKey *persistent_key =3D g_new(SMMUConfigKey, 1); diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index bccbbe0115..90a37fe32d 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -109,6 +109,7 @@ typedef struct SMMUTransTableInfo { uint8_t tsz; /* input range, ie. 2^(64 -tsz)*/ uint8_t granule_sz; /* granule page shift */ bool had; /* hierarchical attribute disable */ + int nscfg; /* Non-secure attribute of Starting-level TT= */ } SMMUTransTableInfo; =20 typedef struct SMMUTLBEntry { @@ -116,6 +117,7 @@ typedef struct SMMUTLBEntry { uint8_t level; uint8_t granule; IOMMUAccessFlags parent_perm; + SMMUSecSID sec_sid; } SMMUTLBEntry; =20 /* Stage-2 configuration. */ @@ -156,6 +158,7 @@ typedef struct SMMUTransCfg { struct SMMUS2Cfg s2cfg; MemTxAttrs txattrs; /* cached transaction attributes */ AddressSpace *as; /* cached address space */ + int sel2; /* Secure EL2 and Secure stage 2 support */ } SMMUTransCfg; =20 typedef struct SMMUDevice { --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 176028195970134.604760909547736; Sun, 12 Oct 2025 08:12:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xk5-000847-2f; Sun, 12 Oct 2025 11:12:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xk3-00083h-LA; Sun, 12 Oct 2025 11:12:11 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xk1-0002PV-HN; Sun, 12 Oct 2025 11:12:11 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwCniGBExeto8lSgAA--.23S2; Sun, 12 Oct 2025 23:12:04 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwD3WedDxetoKHhMAA--.2261S3; Sun, 12 Oct 2025 23:12:03 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 12/21] hw/arm/smmu-common: Implement secure state handling in ptw Date: Sun, 12 Oct 2025 23:12:00 +0800 Message-Id: <20251012151200.4129164-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwD3WedDxetoKHhMAA--.2261S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBaAAAsZ Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3AF47JFW8GrWxGw4UZr4xJFb_yoW3GF13pr WxGr9Ivr4rtFySvrZ3ZF4qv3WrC3yqgF45Kryqkr9akayDtr1kuFWqyr98AFZYgr13J39r Z34jkr4xZrnrX3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=162.243.164.118; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmtyylji0my4xnjqumte4.icoremail.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281963870158500 Content-Type: text/plain; charset="utf-8" Enhance the page table walker to correctly handle secure and non-secure memory accesses. This change introduces logic to select the appropriate address space and enforce architectural security policies during walks. The page table walker now correctly processes Secure Stage 1 translations. Key changes include: - The get_pte function now uses the security context to fetch table entries from either the Secure or Non-secure address space. - The stage 1 walker tracks the security state, respecting the NSCFG and NSTable attributes. It correctly handles the hierarchical security model: if a table descriptor in a secure walk has NSTable=3D1, all subsequent lookups for that walk are forced into the Non-secure space. This is a one-way transition, as specified by the architecture. - A check is added to fault nested translations that produce a Secure IPA when Secure stage 2 is not supported (SMMU_S_IDR1.SEL2 =3D=3D 0). - The final TLB entry is tagged with the correct output address space, ensuring proper memory isolation. Stage 2 translations are currently limited to Non-secure lookups. Full support for Secure Stage 2 translation will be added in a future series. Signed-off-by: Tao Tang --- hw/arm/smmu-common.c | 64 +++++++++++++++++++++++++++++++++++++++----- hw/arm/trace-events | 2 +- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 5fabe30c75..a092bb5a8d 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -399,20 +399,26 @@ void smmu_iotlb_inv_vmid_s1(SMMUState *s, int vmid) * @base_addr[@index] */ static int get_pte(dma_addr_t baseaddr, uint32_t index, uint64_t *pte, - SMMUPTWEventInfo *info) + SMMUPTWEventInfo *info, SMMUSecSID sec_sid) { int ret; dma_addr_t addr =3D baseaddr + index * sizeof(*pte); - + MemTxAttrs attrs =3D smmu_get_txattrs(sec_sid); + AddressSpace *as =3D smmu_get_address_space(sec_sid); + if (!as) { + info->type =3D SMMU_PTW_ERR_WALK_EABT; + info->addr =3D addr; + return -EINVAL; + } /* TODO: guarantee 64-bit single-copy atomicity */ - ret =3D ldq_le_dma(&address_space_memory, addr, pte, MEMTXATTRS_UNSPEC= IFIED); + ret =3D ldq_le_dma(as, addr, pte, attrs); =20 if (ret !=3D MEMTX_OK) { info->type =3D SMMU_PTW_ERR_WALK_EABT; info->addr =3D addr; return -EINVAL; } - trace_smmu_get_pte(baseaddr, index, addr, *pte); + trace_smmu_get_pte(sec_sid, baseaddr, index, addr, *pte); return 0; } =20 @@ -543,6 +549,8 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg *= cfg, =20 baseaddr =3D extract64(tt->ttb, 0, cfg->oas); baseaddr &=3D ~indexmask; + int nscfg =3D tt->nscfg; + bool forced_ns =3D false; /* Track if NSTable=3D1 forced NS mode */ =20 while (level < VMSA_LEVELS) { uint64_t subpage_size =3D 1ULL << level_shift(level, granule_sz); @@ -552,7 +560,10 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg = *cfg, dma_addr_t pte_addr =3D baseaddr + offset * sizeof(pte); uint8_t ap; =20 - if (get_pte(baseaddr, offset, &pte, info)) { + /* Use NS if forced by previous NSTable=3D1 or current nscfg */ + int current_ns =3D forced_ns || nscfg; + SMMUSecSID sec_sid =3D current_ns ? SMMU_SEC_SID_NS : SMMU_SEC_SID= _S; + if (get_pte(baseaddr, offset, &pte, info, sec_sid)) { goto error; } trace_smmu_ptw_level(stage, level, iova, subpage_size, @@ -577,6 +588,26 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg = *cfg, goto error; } } + + /* + * Hierarchical control of Secure/Non-secure accesses: + * If NSTable=3D1 from Secure space, force all subsequent look= ups to + * Non-secure space and ignore future NSTable according to + * (IHI 0070G.b)13.4.1 Stage 1 page permissions and + * (DDI 0487H.a)D8.4.2 Control of Secure or Non-secure memory = access + */ + if (!forced_ns) { + int new_nstable =3D PTE_NSTABLE(pte); + if (!current_ns && new_nstable) { + /* First transition from Secure to Non-secure */ + forced_ns =3D true; + nscfg =3D 1; + } else if (!forced_ns) { + /* Still in original mode, update nscfg normally */ + nscfg =3D new_nstable; + } + /* If forced_ns is already true, ignore NSTable bit */ + } level++; continue; } else if (is_page_pte(pte, level)) { @@ -619,6 +650,13 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg = *cfg, goto error; } =20 + tlbe->sec_sid =3D PTE_NS(pte) ? SMMU_SEC_SID_NS : SMMU_SEC_SID_S; + tlbe->entry.target_as =3D smmu_get_address_space(tlbe->sec_sid); + if (!tlbe->entry.target_as) { + info->type =3D SMMU_PTW_ERR_WALK_EABT; + info->addr =3D gpa; + goto error; + } tlbe->entry.translated_addr =3D gpa; tlbe->entry.iova =3D iova & ~mask; tlbe->entry.addr_mask =3D mask; @@ -688,7 +726,8 @@ static int smmu_ptw_64_s2(SMMUTransCfg *cfg, dma_addr_t pte_addr =3D baseaddr + offset * sizeof(pte); uint8_t s2ap; =20 - if (get_pte(baseaddr, offset, &pte, info)) { + /* Use NS as Secure Stage 2 is not implemented (SMMU_S_IDR1.SEL2 = =3D=3D 0)*/ + if (get_pte(baseaddr, offset, &pte, info, SMMU_SEC_SID_NS)) { goto error; } trace_smmu_ptw_level(stage, level, ipa, subpage_size, @@ -741,6 +780,8 @@ static int smmu_ptw_64_s2(SMMUTransCfg *cfg, goto error_ipa; } =20 + tlbe->sec_sid =3D SMMU_SEC_SID_NS; + tlbe->entry.target_as =3D &address_space_memory; tlbe->entry.translated_addr =3D gpa; tlbe->entry.iova =3D ipa & ~mask; tlbe->entry.addr_mask =3D mask; @@ -825,6 +866,17 @@ int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_add= r_t iova, return ret; } =20 + if (!cfg->sel2 && tlbe->sec_sid > SMMU_SEC_SID_NS) { + /* + * Nested translation with Secure IPA output is not supported if + * Secure Stage 2 is not implemented. + */ + info->type =3D SMMU_PTW_ERR_TRANSLATION; + info->stage =3D SMMU_STAGE_1; + tlbe->entry.perm =3D IOMMU_NONE; + return -EINVAL; + } + ipa =3D CACHED_ENTRY_TO_ADDR(tlbe, iova); ret =3D smmu_ptw_64_s2(cfg, ipa, perm, &tlbe_s2, info); if (ret) { diff --git a/hw/arm/trace-events b/hw/arm/trace-events index 96ebd1b11b..a37e894766 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -16,7 +16,7 @@ smmu_ptw_level(int stage, int level, uint64_t iova, size_= t subpage_size, uint64_ smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pte= addr, uint32_t offset, uint64_t pte) "stage=3D%d level=3D%d base@=3D0x%"PRI= x64" pte@=3D0x%"PRIx64" offset=3D%d pte=3D0x%"PRIx64 smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr,= uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=3D%d level=3D%d i= ova=3D0x%"PRIx64" base@=3D0x%"PRIx64" pte@=3D0x%"PRIx64" pte=3D0x%"PRIx64" = page address =3D 0x%"PRIx64 smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t ptead= dr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=3D%d le= vel=3D%d base@=3D0x%"PRIx64" pte@=3D0x%"PRIx64" pte=3D0x%"PRIx64" iova=3D0x= %"PRIx64" block address =3D 0x%"PRIx64" block size =3D %d MiB" -smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte)= "baseaddr=3D0x%"PRIx64" index=3D0x%x, pteaddr=3D0x%"PRIx64", pte=3D0x%"PRI= x64 +smmu_get_pte(int sec_sid, uint64_t baseaddr, int index, uint64_t pteaddr, = uint64_t pte) "sec_sid=3D%d baseaddr=3D0x%"PRIx64" index=3D0x%x, pteaddr=3D= 0x%"PRIx64", pte=3D0x%"PRIx64"" smmu_iotlb_inv_all(void) "IOTLB invalidate all" smmu_iotlb_inv_asid_vmid(int asid, int vmid) "IOTLB invalidate asid=3D%d v= mid=3D%d" smmu_iotlb_inv_vmid(int vmid) "IOTLB invalidate vmid=3D%d" --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760281983440617.810704569865; Sun, 12 Oct 2025 08:13:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xko-00009B-8U; Sun, 12 Oct 2025 11:12:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xkm-00008r-Fr; Sun, 12 Oct 2025 11:12:56 -0400 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xkk-0002RW-2e; Sun, 12 Oct 2025 11:12:56 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwAX1V1wxetoQiorAA--.32938S2; Sun, 12 Oct 2025 23:12:48 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwC3GuhuxetoNHhMAA--.3096S3; Sun, 12 Oct 2025 23:12:46 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 13/21] hw/arm/smmuv3: Tag IOTLB cache keys with SEC_SID Date: Sun, 12 Oct 2025 23:12:44 +0800 Message-Id: <20251012151244.4129572-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwC3GuhuxetoNHhMAA--.3096S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBagAAsb Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3ZrykJryxGw4ktw1kXw4xWFg_yoWkuw4UpF WxKrn8ur4rJFyfZ3Z7ur4UuFnxZw1qgrWrKrWYgr9Yya4kJ3y8ZF4kC3yUCrWDGr18Grsx Z3y2gr45A3W2q3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=209.97.181.73; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760281987710158500 Content-Type: text/plain; charset="utf-8" To prevent aliasing between secure and non-secure translations for the same address space, the IOTLB lookup key must incorporate the security state of the transaction. This commit expands SMMUIOTLBKey with the SEC_SID, plumbs the new argument through common helpers, and ensures that secure and non-secure TLB entries are treated as distinct entities within the cache. As a final step, this patch ensures the target address space (target_as) from a cached IOTLB entry is correctly propagated to the final translation result. Previously, the result defaulted to the non-secure address space, nullifying the benefits of the security-aware cache key. This change provides robust management for secure TLB entries, preventing TLB pollution between security worlds and allowing for proper initialization by secure software. Signed-off-by: Tao Tang --- hw/arm/smmu-common.c | 25 ++++++++++++--------- hw/arm/smmuv3.c | 42 +++++++++++++++++++++--------------- hw/arm/trace-events | 2 +- include/hw/arm/smmu-common.h | 9 +++++--- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index a092bb5a8d..4131a31ae0 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -86,7 +86,7 @@ static guint smmu_iotlb_key_hash(gconstpointer v) =20 /* Jenkins hash */ a =3D b =3D c =3D JHASH_INITVAL + sizeof(*key); - a +=3D key->asid + key->vmid + key->level + key->tg; + a +=3D key->asid + key->vmid + key->level + key->tg + key->sec_sid; b +=3D extract64(key->iova, 0, 32); c +=3D extract64(key->iova, 32, 32); =20 @@ -102,14 +102,15 @@ static gboolean smmu_iotlb_key_equal(gconstpointer v1= , gconstpointer v2) =20 return (k1->asid =3D=3D k2->asid) && (k1->iova =3D=3D k2->iova) && (k1->level =3D=3D k2->level) && (k1->tg =3D=3D k2->tg) && - (k1->vmid =3D=3D k2->vmid); + (k1->vmid =3D=3D k2->vmid) && (k1->sec_sid =3D=3D k2->sec_sid); } =20 SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uint64_t iova, - uint8_t tg, uint8_t level) + uint8_t tg, uint8_t level, + SMMUSecSID sec_sid) { SMMUIOTLBKey key =3D {.asid =3D asid, .vmid =3D vmid, .iova =3D iova, - .tg =3D tg, .level =3D level}; + .tg =3D tg, .level =3D level, .sec_sid =3D sec_sid= }; =20 return key; } @@ -131,7 +132,7 @@ static SMMUTLBEntry *smmu_iotlb_lookup_all_levels(SMMUS= tate *bs, SMMUIOTLBKey key; =20 key =3D smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid, - iova & ~mask, tg, level); + iova & ~mask, tg, level, cfg->sec_sid); entry =3D g_hash_table_lookup(bs->iotlb, &key); if (entry) { break; @@ -195,7 +196,7 @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg= , SMMUTLBEntry *new) } =20 *key =3D smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid, new->entry.iov= a, - tg, new->level); + tg, new->level, cfg->sec_sid); trace_smmu_iotlb_insert(cfg->asid, cfg->s2cfg.vmid, new->entry.iova, tg, new->level); g_hash_table_insert(bs->iotlb, key, new); @@ -314,13 +315,15 @@ void smmu_configs_inv_sdev(SMMUState *s, SMMUDevice *= sdev) } =20 void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova, - uint8_t tg, uint64_t num_pages, uint8_t ttl) + uint8_t tg, uint64_t num_pages, uint8_t ttl, + SMMUSecSID sec_sid) { /* if tg is not set we use 4KB range invalidation */ uint8_t granule =3D tg ? tg * 2 + 10 : 12; =20 if (ttl && (num_pages =3D=3D 1) && (asid >=3D 0)) { - SMMUIOTLBKey key =3D smmu_get_iotlb_key(asid, vmid, iova, tg, ttl); + SMMUIOTLBKey key =3D smmu_get_iotlb_key(asid, vmid, iova, + tg, ttl, sec_sid); =20 if (g_hash_table_remove(s->iotlb, &key)) { return; @@ -346,13 +349,15 @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, int = vmid, dma_addr_t iova, * in Stage-1 invalidation ASID =3D -1, means don't care. */ void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_addr_t ipa, uint8_t tg, - uint64_t num_pages, uint8_t ttl) + uint64_t num_pages, uint8_t ttl, + SMMUSecSID sec_sid) { uint8_t granule =3D tg ? tg * 2 + 10 : 12; int asid =3D -1; =20 if (ttl && (num_pages =3D=3D 1)) { - SMMUIOTLBKey key =3D smmu_get_iotlb_key(asid, vmid, ipa, tg, ttl); + SMMUIOTLBKey key =3D smmu_get_iotlb_key(asid, vmid, ipa, + tg, ttl, sec_sid); =20 if (g_hash_table_remove(s->iotlb, &key)) { return; diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 3686056d8e..f9395c3821 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1125,6 +1125,7 @@ epilogue: entry.perm =3D cached_entry->entry.perm; entry.translated_addr =3D CACHED_ENTRY_TO_ADDR(cached_entry, addr); entry.addr_mask =3D cached_entry->entry.addr_mask; + entry.target_as =3D cached_entry->entry.target_as; trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr, entry.translated_addr, entry.perm, cfg->stage); @@ -1170,15 +1171,16 @@ epilogue: * @tg: translation granule (if communicated through range invalidation) * @num_pages: number of @granule sized pages (if tg !=3D 0), otherwise 1 * @stage: Which stage(1 or 2) is used + * @sec_sid: security stream ID */ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, IOMMUNotifier *n, int asid, int vmid, dma_addr_t iova, uint8_t tg, - uint64_t num_pages, int stage) + uint64_t num_pages, int stage, + SMMUSecSID sec_sid) { SMMUDevice *sdev =3D container_of(mr, SMMUDevice, iommu); - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUEventInfo eventinfo =3D {.sec_sid =3D sec_sid, .inval_ste_allowed =3D true}; SMMUTransCfg *cfg =3D smmuv3_get_config(sdev, &eventinfo, sec_sid); @@ -1226,7 +1228,7 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, } =20 event.type =3D IOMMU_NOTIFIER_UNMAP; - event.entry.target_as =3D &address_space_memory; + event.entry.target_as =3D smmu_get_address_space(sec_sid); event.entry.iova =3D iova; event.entry.addr_mask =3D num_pages * (1 << granule) - 1; event.entry.perm =3D IOMMU_NONE; @@ -1237,7 +1239,8 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, /* invalidate an asid/vmid/iova range tuple in all mr's */ static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova, uint8_t tg, - uint64_t num_pages, int stage) + uint64_t num_pages, int stage, + SMMUSecSID sec_sid) { SMMUDevice *sdev; =20 @@ -1249,12 +1252,14 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s,= int asid, int vmid, iova, tg, num_pages, stage); =20 IOMMU_NOTIFIER_FOREACH(n, mr) { - smmuv3_notify_iova(mr, n, asid, vmid, iova, tg, num_pages, sta= ge); + smmuv3_notify_iova(mr, n, asid, vmid, iova, tg, + num_pages, stage, sec_sid); } } } =20 -static void smmuv3_range_inval(SMMUState *s, Cmd *cmd, SMMUStage stage) +static void smmuv3_range_inval(SMMUState *s, Cmd *cmd, SMMUStage stage, + SMMUSecSID sec_sid) { dma_addr_t end, addr =3D CMD_ADDR(cmd); uint8_t type =3D CMD_TYPE(cmd); @@ -1279,12 +1284,13 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *c= md, SMMUStage stage) } =20 if (!tg) { - trace_smmuv3_range_inval(vmid, asid, addr, tg, 1, ttl, leaf, stage= ); - smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, 1, stage); + trace_smmuv3_range_inval(sec_sid, vmid, asid, addr, + tg, 1, ttl, leaf, stage); + smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, 1, stage, sec_s= id); if (stage =3D=3D SMMU_STAGE_1) { - smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl); + smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl, sec_sid); } else { - smmu_iotlb_inv_ipa(s, vmid, addr, tg, 1, ttl); + smmu_iotlb_inv_ipa(s, vmid, addr, tg, 1, ttl, sec_sid); } return; } @@ -1301,13 +1307,15 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *c= md, SMMUStage stage) uint64_t mask =3D dma_aligned_pow2_mask(addr, end, 64); =20 num_pages =3D (mask + 1) >> granule; - trace_smmuv3_range_inval(vmid, asid, addr, tg, num_pages, - ttl, leaf, stage); - smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, num_pages, stag= e); + trace_smmuv3_range_inval(sec_sid, vmid, asid, addr, tg, + num_pages, ttl, leaf, stage); + smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, + num_pages, stage, sec_sid); if (stage =3D=3D SMMU_STAGE_1) { - smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, num_pages, ttl); + smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, + num_pages, ttl, sec_sid); } else { - smmu_iotlb_inv_ipa(s, vmid, addr, tg, num_pages, ttl); + smmu_iotlb_inv_ipa(s, vmid, addr, tg, num_pages, ttl, sec_sid); } addr +=3D mask + 1; } @@ -1474,7 +1482,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) cmd_error =3D SMMU_CERROR_ILL; break; } - smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1); + smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1, SMMU_SEC_SID_NS); break; case SMMU_CMD_TLBI_S12_VMALL: { @@ -1499,7 +1507,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) * As currently only either s1 or s2 are supported * we can reuse same function for s2. */ - smmuv3_range_inval(bs, &cmd, SMMU_STAGE_2); + smmuv3_range_inval(bs, &cmd, SMMU_STAGE_2, SMMU_SEC_SID_NS); break; case SMMU_CMD_TLBI_EL3_ALL: case SMMU_CMD_TLBI_EL3_VA: diff --git a/hw/arm/trace-events b/hw/arm/trace-events index a37e894766..434d6abfc2 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -56,7 +56,7 @@ smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=3D0= x%x - end=3D0x%x" smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=3D0x%x" smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint= 32_t perc) "Config cache HIT for sid=3D0x%x (hits=3D%d, misses=3D%d, hit ra= te=3D%d)" smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uin= t32_t perc) "Config cache MISS for sid=3D0x%x (hits=3D%d, misses=3D%d, hit = rate=3D%d)" -smmuv3_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t= num_pages, uint8_t ttl, bool leaf, int stage) "vmid=3D%d asid=3D%d addr=3D= 0x%"PRIx64" tg=3D%d num_pages=3D0x%"PRIx64" ttl=3D%d leaf=3D%d stage=3D%d" +smmuv3_range_inval(int sec_sid, int vmid, int asid, uint64_t addr, uint8_t= tg, uint64_t num_pages, uint8_t ttl, bool leaf, int stage) "sec_sid=3D%d v= mid=3D%d asid=3D%d addr=3D0x%"PRIx64" tg=3D%d num_pages=3D0x%"PRIx64" ttl= =3D%d leaf=3D%d stage=3D%d" smmuv3_cmdq_tlbi_nh(int vmid) "vmid=3D%d" smmuv3_cmdq_tlbi_nsnh(void) "" smmuv3_cmdq_tlbi_nh_asid(int asid) "asid=3D%d" diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 90a37fe32d..211fc7c2d0 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -183,6 +183,7 @@ typedef struct SMMUIOTLBKey { int vmid; uint8_t tg; uint8_t level; + SMMUSecSID sec_sid; } SMMUIOTLBKey; =20 typedef struct SMMUConfigKey { @@ -264,16 +265,18 @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTr= ansCfg *cfg, SMMUTransTableInfo *tt, hwaddr iova); void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *ent= ry); SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uint64_t iova, - uint8_t tg, uint8_t level); + uint8_t tg, uint8_t level, SMMUSecSID sec_= sid); SMMUConfigKey smmu_get_config_key(SMMUDevice *sdev, SMMUSecSID sec_sid); void smmu_iotlb_inv_all(SMMUState *s); void smmu_iotlb_inv_asid_vmid(SMMUState *s, int asid, int vmid); void smmu_iotlb_inv_vmid(SMMUState *s, int vmid); void smmu_iotlb_inv_vmid_s1(SMMUState *s, int vmid); void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova, - uint8_t tg, uint64_t num_pages, uint8_t ttl); + uint8_t tg, uint64_t num_pages, uint8_t ttl, + SMMUSecSID sec_sid); void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_addr_t ipa, uint8_t tg, - uint64_t num_pages, uint8_t ttl); + uint64_t num_pages, uint8_t ttl, + SMMUSecSID sec_sid); void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range); void smmu_configs_inv_sdev(SMMUState *s, SMMUDevice *sdev); /* Unmap the range of all the notifiers registered to any IOMMU mr */ --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17602820273081018.7520359344687; Sun, 12 Oct 2025 08:13:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xlD-0000ZS-02; Sun, 12 Oct 2025 11:13:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xl9-0000SC-WB; Sun, 12 Oct 2025 11:13:21 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xl7-0002SI-Dn; Sun, 12 Oct 2025 11:13:19 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwA3GGCKxetoaFagAA--.103S2; Sun, 12 Oct 2025 23:13:14 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXO+mIxetoRXhMAA--.1376S3; Sun, 12 Oct 2025 23:13:13 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 14/21] hw/arm/smmuv3: Add access checks for MMIO registers Date: Sun, 12 Oct 2025 23:13:03 +0800 Message-Id: <20251012151303.4129730-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXO+mIxetoRXhMAA--.1376S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBbAAAsd Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoW3tw4xXF1kKFy8tr1kJF47urg_yoW8XFWfXo WFkr45Zw48Z3Z7C39avFs7X3WkJF4kCw47Aw15XrW2vw4kJr4rXr97GrZ3urya9rW7JrWk tw18Zw4fZFWrJFs5n29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3UbIjqfuFe4nvWSU8nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UU UUUUUUU== Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=162.243.164.118; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmtyylji0my4xnjqumte4.icoremail.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282030130158500 Content-Type: text/plain; charset="utf-8" The SMMUv3 model was missing checks for register accessibility under certain conditions. This allowed guest software to write to registers like STRTAB_BASE when they should be read-only, or read from GERROR_IRQ_CFG registers when they should be RES0. This patch fixes this by introducing helper functions, such as the smmu_(reg_name)_writable pattern, to encapsulate the architectural access rules. In addition, writes to registers like STRTAB_BASE, queue bases, and IRQ configurations are now masked to correctly handle reserved bits. The MMIO handlers are updated to call these functions before accessing registers. To purely fix the missing checks without introducing new functionality, the security context in the MMIO handlers is explicitly fixed to Non-secure. This ensures that the scope of this patch is limited to fixing existing Non-secure logic. If a register is not accessible, the access is now correctly handled and a guest error is logged, bringing the model's behavior in line with the specification. Fixes: fae4be38b35d ("hw/arm/smmuv3: Implement MMIO write operations") Fixes: 10a83cb9887e ("hw/arm/smmuv3: Skeleton") Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 298 insertions(+), 6 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index f9395c3821..f161dd3eff 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1321,6 +1321,127 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *c= md, SMMUStage stage, } } =20 +static inline int smmuv3_get_cr0ack_smmuen(SMMUv3State *s, SMMUSecSID sec_= sid) +{ + return FIELD_EX32(s->bank[sec_sid].cr0ack, CR0, SMMUEN); +} + +static inline bool smmuv3_is_smmu_enabled(SMMUv3State *s, SMMUSecSID sec_s= id) +{ + int cr0_smmuen =3D smmu_enabled(s, sec_sid); + int cr0ack_smmuen =3D smmuv3_get_cr0ack_smmuen(s, sec_sid); + return (cr0_smmuen =3D=3D 0 && cr0ack_smmuen =3D=3D 0); +} + +/* Check if STRTAB_BASE register is writable */ +static bool smmu_strtab_base_writable(SMMUv3State *s, SMMUSecSID sec_sid) +{ + /* Check TABLES_PRESET - use NS bank as it's the global setting */ + if (FIELD_EX32(s->bank[sec_sid].idr[1], IDR1, TABLES_PRESET)) { + return false; + } + + /* Check SMMUEN conditions for the specific security domain */ + return smmuv3_is_smmu_enabled(s, sec_sid); +} + +static inline int smmuv3_get_cr0_cmdqen(SMMUv3State *s, SMMUSecSID sec_sid) +{ + return FIELD_EX32(s->bank[sec_sid].cr[0], CR0, CMDQEN); +} + +static inline int smmuv3_get_cr0ack_cmdqen(SMMUv3State *s, SMMUSecSID sec_= sid) +{ + return FIELD_EX32(s->bank[sec_sid].cr0ack, CR0, CMDQEN); +} + +static inline int smmuv3_get_cr0_eventqen(SMMUv3State *s, SMMUSecSID sec_s= id) +{ + return FIELD_EX32(s->bank[sec_sid].cr[0], CR0, EVENTQEN); +} + +static inline int smmuv3_get_cr0ack_eventqen(SMMUv3State *s, SMMUSecSID se= c_sid) +{ + return FIELD_EX32(s->bank[sec_sid].cr0ack, CR0, EVENTQEN); +} + +/* Check if MSI is supported */ +static inline bool smmu_msi_supported(SMMUv3State *s, SMMUSecSID sec_sid) +{ + return FIELD_EX32(s->bank[sec_sid].idr[0], IDR0, MSI); +} + +/* Check if secure GERROR_IRQ_CFGx registers are writable */ +static inline bool smmu_gerror_irq_cfg_writable(SMMUv3State *s, + SMMUSecSID sec_sid) +{ + if (!smmu_msi_supported(s, sec_sid)) { + return false; + } + + bool ctrl_en =3D FIELD_EX32(s->bank[sec_sid].irq_ctrl, + IRQ_CTRL, GERROR_IRQEN); + return !ctrl_en; +} + +/* Check if CMDQEN is disabled */ +static bool smmu_cmdqen_disabled(SMMUv3State *s, SMMUSecSID sec_sid) +{ + int cr0_cmdqen =3D smmuv3_get_cr0_cmdqen(s, sec_sid); + int cr0ack_cmdqen =3D smmuv3_get_cr0ack_cmdqen(s, sec_sid); + return (cr0_cmdqen =3D=3D 0 && cr0ack_cmdqen =3D=3D 0); +} + +/* Check if CMDQ_BASE register is writable */ +static bool smmu_cmdq_base_writable(SMMUv3State *s, SMMUSecSID sec_sid) +{ + /* Check TABLES_PRESET - use NS bank as it's the global setting */ + if (FIELD_EX32(s->bank[sec_sid].idr[1], IDR1, QUEUES_PRESET)) { + return false; + } + + return smmu_cmdqen_disabled(s, sec_sid); +} + +/* Check if EVENTQEN is disabled */ +static bool smmu_eventqen_disabled(SMMUv3State *s, SMMUSecSID sec_sid) +{ + int cr0_eventqen =3D smmuv3_get_cr0_eventqen(s, sec_sid); + int cr0ack_eventqen =3D smmuv3_get_cr0ack_eventqen(s, sec_sid); + return (cr0_eventqen =3D=3D 0 && cr0ack_eventqen =3D=3D 0); +} + +static bool smmu_idr1_queue_preset(SMMUv3State *s, SMMUSecSID sec_sid) +{ + return FIELD_EX32(s->bank[sec_sid].idr[1], IDR1, QUEUES_PRESET); +} + +/* Check if EVENTQ_BASE register is writable */ +static bool smmu_eventq_base_writable(SMMUv3State *s, SMMUSecSID sec_sid) +{ + /* Check TABLES_PRESET - use NS bank as it's the global setting */ + if (smmu_idr1_queue_preset(s, sec_sid)) { + return false; + } + + return smmu_eventqen_disabled(s, sec_sid); +} + +static bool smmu_irq_ctl_evtq_irqen_disabled(SMMUv3State *s, SMMUSecSID se= c_sid) +{ + return FIELD_EX32(s->bank[sec_sid].irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN); +} + +/* Check if EVENTQ_IRQ_CFGx is writable */ +static bool smmu_eventq_irq_cfg_writable(SMMUv3State *s, SMMUSecSID sec_si= d) +{ + if (smmu_msi_supported(s, sec_sid)) { + return false; + } + + return smmu_irq_ctl_evtq_irqen_disabled(s, sec_sid); +} + static int smmuv3_cmdq_consume(SMMUv3State *s) { SMMUState *bs =3D ARM_SMMU(s); @@ -1561,27 +1682,59 @@ static MemTxResult smmu_writell(SMMUv3State *s, hwa= ddr offset, =20 switch (offset) { case A_GERROR_IRQ_CFG0: - bank->gerror_irq_cfg0 =3D data; + if (!smmu_gerror_irq_cfg_writable(s, reg_sec_sid)) { + /* SMMU_(*_)_IRQ_CTRL.GERROR_IRQEN =3D=3D 1: IGNORED this writ= e */ + qemu_log_mask(LOG_GUEST_ERROR, "GERROR_IRQ_CFG0 write ignored:= " + "register is RO when IRQ enabled\n"); + return MEMTX_OK; + } + + bank->gerror_irq_cfg0 =3D data & SMMU_GERROR_IRQ_CFG0_RESERVED; return MEMTX_OK; case A_STRTAB_BASE: - bank->strtab_base =3D data; + if (!smmu_strtab_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "STRTAB_BASE write ignored: register is RO\n"); + return MEMTX_OK; + } + + /* Clear reserved bits according to spec */ + bank->strtab_base =3D data & SMMU_STRTAB_BASE_RESERVED; return MEMTX_OK; case A_CMDQ_BASE: - bank->cmdq.base =3D data; + if (!smmu_cmdq_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "CMDQ_BASE write ignored: register is RO\n"); + return MEMTX_OK; + } + + bank->cmdq.base =3D data & SMMU_QUEUE_BASE_RESERVED; bank->cmdq.log2size =3D extract64(bank->cmdq.base, 0, 5); if (bank->cmdq.log2size > SMMU_CMDQS) { bank->cmdq.log2size =3D SMMU_CMDQS; } return MEMTX_OK; case A_EVENTQ_BASE: - bank->eventq.base =3D data; + if (!smmu_eventq_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_BASE write ignored: register is RO\n"); + return MEMTX_OK; + } + + bank->eventq.base =3D data & SMMU_QUEUE_BASE_RESERVED; bank->eventq.log2size =3D extract64(bank->eventq.base, 0, 5); if (bank->eventq.log2size > SMMU_EVENTQS) { bank->eventq.log2size =3D SMMU_EVENTQS; } return MEMTX_OK; case A_EVENTQ_IRQ_CFG0: - bank->eventq_irq_cfg0 =3D data; + if (!smmu_eventq_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_IRQ_CFG0 write ignored: register is RO\n= "); + return MEMTX_OK; + } + + bank->eventq_irq_cfg0 =3D data & SMMU_EVENTQ_IRQ_CFG0_RESERVED; return MEMTX_OK; default: qemu_log_mask(LOG_UNIMP, @@ -1608,7 +1761,15 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, bank->cr[1] =3D data; return MEMTX_OK; case A_CR2: - bank->cr[2] =3D data; + if (smmuv3_is_smmu_enabled(s, reg_sec_sid)) { + /* Allow write: SMMUEN is 0 in both CR0 and CR0ACK */ + bank->cr[2] =3D data; + } else { + /* CONSTRAINED UNPREDICTABLE behavior: Ignore this write */ + qemu_log_mask(LOG_GUEST_ERROR, + "CR2 write ignored: register is read-only when " + "CR0.SMMUEN or CR0ACK.SMMUEN is set\n"); + } return MEMTX_OK; case A_IRQ_CTRL: bank->irq_ctrl =3D data; @@ -1622,12 +1783,31 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, smmuv3_cmdq_consume(s); return MEMTX_OK; case A_GERROR_IRQ_CFG0: /* 64b */ + if (!smmu_gerror_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, "GERROR_IRQ_CFG0 write ignored:= " + "register is RO when IRQ enabled\n"); + return MEMTX_OK; + } + + data &=3D SMMU_GERROR_IRQ_CFG0_RESERVED; bank->gerror_irq_cfg0 =3D deposit64(bank->gerror_irq_cfg0, 0, 32, = data); return MEMTX_OK; case A_GERROR_IRQ_CFG0 + 4: + if (!smmu_gerror_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, "GERROR_IRQ_CFG0 + 4 write igno= red: " + "register is RO when IRQ enabled\n"); + return MEMTX_OK; + } + bank->gerror_irq_cfg0 =3D deposit64(bank->gerror_irq_cfg0, 32, 32,= data); return MEMTX_OK; case A_GERROR_IRQ_CFG1: + if (!smmu_gerror_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, "GERROR_IRQ_CFG1 write ignored:= " + "register is RO when IRQ enabled\n"); + return MEMTX_OK; + } + bank->gerror_irq_cfg1 =3D data; return MEMTX_OK; case A_GERROR_IRQ_CFG2: @@ -1644,12 +1824,32 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, } return MEMTX_OK; case A_STRTAB_BASE: /* 64b */ + if (!smmu_strtab_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "STRTAB_BASE write ignored: register is RO\n"); + return MEMTX_OK; + } + + data &=3D SMMU_STRTAB_BASE_RESERVED; bank->strtab_base =3D deposit64(bank->strtab_base, 0, 32, data); return MEMTX_OK; case A_STRTAB_BASE + 4: + if (!smmu_strtab_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "STRTAB_BASE + 4 write ignored: register is RO\n= "); + return MEMTX_OK; + } + + data &=3D SMMU_STRTAB_BASE_RESERVED; bank->strtab_base =3D deposit64(bank->strtab_base, 32, 32, data); return MEMTX_OK; case A_STRTAB_BASE_CFG: + if (!smmu_strtab_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "STRTAB_BASE_CFG write ignored: register is RO\n= "); + return MEMTX_OK; + } + bank->strtab_base_cfg =3D data; if (FIELD_EX32(data, STRTAB_BASE_CFG, FMT) =3D=3D 1) { bank->sid_split =3D FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT); @@ -1657,6 +1857,13 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, } return MEMTX_OK; case A_CMDQ_BASE: /* 64b */ + if (!smmu_cmdq_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "CMDQ_BASE write ignored: register is RO\n"); + return MEMTX_OK; + } + + data &=3D SMMU_QUEUE_BASE_RESERVED; bank->cmdq.base =3D deposit64(bank->cmdq.base, 0, 32, data); bank->cmdq.log2size =3D extract64(bank->cmdq.base, 0, 5); if (bank->cmdq.log2size > SMMU_CMDQS) { @@ -1664,6 +1871,13 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, } return MEMTX_OK; case A_CMDQ_BASE + 4: /* 64b */ + if (!smmu_cmdq_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "CMDQ_BASE + 4 write ignored: register is RO\n"); + return MEMTX_OK; + } + + data &=3D SMMU_QUEUE_BASE_RESERVED; bank->cmdq.base =3D deposit64(bank->cmdq.base, 32, 32, data); return MEMTX_OK; case A_CMDQ_PROD: @@ -1671,9 +1885,22 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, smmuv3_cmdq_consume(s); return MEMTX_OK; case A_CMDQ_CONS: + if (!smmu_cmdqen_disabled(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "CMDQ_CONS write ignored: register is RO\n"); + return MEMTX_OK; + } + bank->cmdq.cons =3D data; return MEMTX_OK; case A_EVENTQ_BASE: /* 64b */ + if (!smmu_eventq_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_BASE write ignored: register is RO\n"); + return MEMTX_OK; + } + + data &=3D SMMU_QUEUE_BASE_RESERVED; bank->eventq.base =3D deposit64(bank->eventq.base, 0, 32, data); bank->eventq.log2size =3D extract64(bank->eventq.base, 0, 5); if (bank->eventq.log2size > SMMU_EVENTQS) { @@ -1681,24 +1908,63 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, } return MEMTX_OK; case A_EVENTQ_BASE + 4: + if (!smmu_eventq_base_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_BASE + 4 write ignored: register is RO\n= "); + return MEMTX_OK; + } + + data &=3D SMMU_QUEUE_BASE_RESERVED; bank->eventq.base =3D deposit64(bank->eventq.base, 32, 32, data); return MEMTX_OK; case A_EVENTQ_PROD: + if (!smmu_eventqen_disabled(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_PROD write ignored: register is RO\n"); + return MEMTX_OK; + } + bank->eventq.prod =3D data; return MEMTX_OK; case A_EVENTQ_CONS: bank->eventq.cons =3D data; return MEMTX_OK; case A_EVENTQ_IRQ_CFG0: /* 64b */ + if (!smmu_eventq_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_IRQ_CFG0 write ignored: register is RO\n= "); + return MEMTX_OK; + } + + data &=3D SMMU_EVENTQ_IRQ_CFG0_RESERVED; bank->eventq_irq_cfg0 =3D deposit64(bank->eventq_irq_cfg0, 0, 32, = data); return MEMTX_OK; case A_EVENTQ_IRQ_CFG0 + 4: + if (!smmu_eventq_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_IRQ_CFG0+4 write ignored: register is RO= \n"); + return MEMTX_OK; + } + + data &=3D SMMU_EVENTQ_IRQ_CFG0_RESERVED; bank->eventq_irq_cfg0 =3D deposit64(bank->eventq_irq_cfg0, 32, 32,= data); return MEMTX_OK; case A_EVENTQ_IRQ_CFG1: + if (!smmu_eventq_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_IRQ_CFG1 write ignored: register is RO\n= "); + return MEMTX_OK; + } + bank->eventq_irq_cfg1 =3D data; return MEMTX_OK; case A_EVENTQ_IRQ_CFG2: + if (!smmu_eventq_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, + "EVENTQ_IRQ_CFG2 write ignored: register is RO\n= "); + return MEMTX_OK; + } + bank->eventq_irq_cfg2 =3D data; return MEMTX_OK; default: @@ -1743,6 +2009,12 @@ static MemTxResult smmu_readll(SMMUv3State *s, hwadd= r offset, =20 switch (offset) { case A_GERROR_IRQ_CFG0: + /* SMMU_(*_)GERROR_IRQ_CFG0 BOTH check SMMU_IDR0.MSI */ + if (!smmu_msi_supported(s, reg_sec_sid)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + *data =3D bank->gerror_irq_cfg0; return MEMTX_OK; case A_STRTAB_BASE: @@ -1811,15 +2083,35 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwadd= r offset, *data =3D bank->gerrorn; return MEMTX_OK; case A_GERROR_IRQ_CFG0: /* 64b */ + if (!smmu_msi_supported(s, reg_sec_sid)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + *data =3D extract64(bank->gerror_irq_cfg0, 0, 32); return MEMTX_OK; case A_GERROR_IRQ_CFG0 + 4: + if (!smmu_msi_supported(s, reg_sec_sid)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + *data =3D extract64(bank->gerror_irq_cfg0, 32, 32); return MEMTX_OK; case A_GERROR_IRQ_CFG1: + if (!smmu_msi_supported(s, reg_sec_sid)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + *data =3D bank->gerror_irq_cfg1; return MEMTX_OK; case A_GERROR_IRQ_CFG2: + if (!smmu_msi_supported(s, reg_sec_sid)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + *data =3D bank->gerror_irq_cfg2; return MEMTX_OK; case A_STRTAB_BASE: /* 64b */ --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760282046710226.71890333785166; Sun, 12 Oct 2025 08:14:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xll-00019F-DU; Sun, 12 Oct 2025 11:13:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xlT-000135-Pe; Sun, 12 Oct 2025 11:13:43 -0400 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xlR-0002VP-O7; Sun, 12 Oct 2025 11:13:39 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwBXXJidxeto1VagAA--.18S2; Sun, 12 Oct 2025 23:13:33 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwD3WuicxetoTHhMAA--.3018S3; Sun, 12 Oct 2025 23:13:33 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 15/21] hw/arm/smmuv3: Determine register bank from MMIO offset Date: Sun, 12 Oct 2025 23:13:31 +0800 Message-Id: <20251012151331.4130048-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwD3WuicxetoTHhMAA--.3018S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBbgAAsf Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3AFy7Gr47CF4DXF18uFW8Crg_yoWxXryfp3 yDJF1Sgr1DKa1SqwsxJa1UC3WfCan7Kr1akr9xK34Du3y2kw1xtayvy34fur1DGFy3Zrs8 JFW5GrW7ur4DZ3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=209.97.181.73; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282049538154100 Content-Type: text/plain; charset="utf-8" Modify the main MMIO handlers (smmu_write_mmio, smmu_read_mmio) to determine the security state of the target register based on its memory-mapped offset. By checking if the offset is within the secure register space (>=3D SMMU_SECURE_REG_START), the handlers can deduce the register's SEC_SID (reg_sec_sid). This SID is then passed down to the register access helper functions (smmu_writel, smmu_readl, etc.). Inside these helpers, the switch statement now operates on a masked, relative offset: uint32_t reg_offset =3D offset & 0xfff; switch (reg_offset) { ... } This design leverages a key feature of the SMMU specification: registers with the same function across different security states (Non-secure, Realm, Root) share the same relative offset. This avoids significant code duplication. The reg_sec_sid passed from the MMIO handler determines which security bank to operate on, while the masked offset identifies the specific register within that bank. It is important to distinguish between the security state of the register itself and the security state of the access. A higher-privilege security state is permitted to access registers belonging to a lower-privilege state, but the reverse is not allowed. This patch lays the groundwork for enforcing such rules. For future compatibility with Realm and Root states, the logic in the else block corresponding to the secure offset check: if (offset >=3D SMMU_SECURE_REG_START) { reg_sec_sid =3D SMMU_SEC_SID_S; } else { /* Future Realm/Root handling */ } will need to be expanded. This will be necessary to differentiate between the Root Control Page and Realm Register Pages, especially since the Root Control Page is IMPLEMENTATION DEFINED. Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 61 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index f161dd3eff..100caeeb35 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1675,12 +1675,13 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) } =20 static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset, - uint64_t data, MemTxAttrs attrs) + uint64_t data, MemTxAttrs attrs, + SMMUSecSID reg_sec_sid) { - SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + uint32_t reg_offset =3D offset & 0xfff; =20 - switch (offset) { + switch (reg_offset) { case A_GERROR_IRQ_CFG0: if (!smmu_gerror_irq_cfg_writable(s, reg_sec_sid)) { /* SMMU_(*_)_IRQ_CTRL.GERROR_IRQEN =3D=3D 1: IGNORED this writ= e */ @@ -1745,12 +1746,13 @@ static MemTxResult smmu_writell(SMMUv3State *s, hwa= ddr offset, } =20 static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset, - uint64_t data, MemTxAttrs attrs) + uint64_t data, MemTxAttrs attrs, + SMMUSecSID reg_sec_sid) { - SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + uint32_t reg_offset =3D offset & 0xfff; =20 - switch (offset) { + switch (reg_offset) { case A_CR0: bank->cr[0] =3D data; bank->cr0ack =3D data & ~SMMU_CR0_RESERVED; @@ -1985,12 +1987,33 @@ static MemTxResult smmu_write_mmio(void *opaque, hw= addr offset, uint64_t data, /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ offset &=3D ~0x10000; =20 + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; + /* + * The security state of the access (MemTxAttrs attrs) may differ from= the + * security state to which the register belongs. Future support will i= nclude + * Realm and Root security states. + * + * The SMMU architecture specifies that Realm, Root, and Non-secure + * registers share the same offset layout within the last 4 hexadecimal + * digits (16 bits) of the address. Only Secure state registers are + * mapped to a higher address space, starting from + * SMMU_SECURE_REG_START (0x8000). + * + * Therefore, we can directly use the offset to distinguish Secure + * registers. When Realm and Root support is needed in the future, we + * only need to enhance the 'else' block of the corresponding 'if' + * statement to handle those specific security states. + */ + if (offset >=3D SMMU_SECURE_REG_START) { + reg_sec_sid =3D SMMU_SEC_SID_S; + } + switch (size) { case 8: - r =3D smmu_writell(s, offset, data, attrs); + r =3D smmu_writell(s, offset, data, attrs, reg_sec_sid); break; case 4: - r =3D smmu_writel(s, offset, data, attrs); + r =3D smmu_writel(s, offset, data, attrs, reg_sec_sid); break; default: r =3D MEMTX_ERROR; @@ -2002,12 +2025,13 @@ static MemTxResult smmu_write_mmio(void *opaque, hw= addr offset, uint64_t data, } =20 static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset, - uint64_t *data, MemTxAttrs attrs) + uint64_t *data, MemTxAttrs attrs, + SMMUSecSID reg_sec_sid) { - SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + uint32_t reg_offset =3D offset & 0xfff; =20 - switch (offset) { + switch (reg_offset) { case A_GERROR_IRQ_CFG0: /* SMMU_(*_)GERROR_IRQ_CFG0 BOTH check SMMU_IDR0.MSI */ if (!smmu_msi_supported(s, reg_sec_sid)) { @@ -2036,12 +2060,13 @@ static MemTxResult smmu_readll(SMMUv3State *s, hwad= dr offset, } =20 static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset, - uint64_t *data, MemTxAttrs attrs) + uint64_t *data, MemTxAttrs attrs, + SMMUSecSID reg_sec_sid) { - SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); + uint32_t reg_offset =3D offset & 0xfff; =20 - switch (offset) { + switch (reg_offset) { case A_IDREGS ... A_IDREGS + 0x2f: *data =3D smmuv3_idreg(offset - A_IDREGS); return MEMTX_OK; @@ -2165,13 +2190,17 @@ static MemTxResult smmu_read_mmio(void *opaque, hwa= ddr offset, uint64_t *data, =20 /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ offset &=3D ~0x10000; + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; + if (offset >=3D SMMU_SECURE_REG_START) { + reg_sec_sid =3D SMMU_SEC_SID_S; + } =20 switch (size) { case 8: - r =3D smmu_readll(s, offset, data, attrs); + r =3D smmu_readll(s, offset, data, attrs, reg_sec_sid); break; case 4: - r =3D smmu_readl(s, offset, data, attrs); + r =3D smmu_readl(s, offset, data, attrs, reg_sec_sid); break; default: r =3D MEMTX_ERROR; --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760282065938335.25072292195875; Sun, 12 Oct 2025 08:14:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xlt-0001Rp-Hz; Sun, 12 Oct 2025 11:14:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xlr-0001RA-SZ; Sun, 12 Oct 2025 11:14:03 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xlp-0002WE-Ma; Sun, 12 Oct 2025 11:14:03 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwA3Ppq1xetoT1egAA--.31S2; Sun, 12 Oct 2025 23:13:57 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwB32+izxetoVXhMAA--.3235S3; Sun, 12 Oct 2025 23:13:56 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 16/21] hw/arm/smmuv3: Implement SMMU_S_INIT register Date: Sun, 12 Oct 2025 23:13:51 +0800 Message-Id: <20251012151351.4130239-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwB32+izxetoVXhMAA--.3235S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBcAAAsB Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxJF13XFWDXw4rZr17uFy7GFg_yoW5uF4kpF WkGr98Kr4UZ3Wa9FsIkw4xAFn5u34vgr17CrZxGr9av3Wvy3yDZa1DtrW3CFZ8Wr1UG3y7 Gw4SgFsxWr1UX3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282069768154100 Content-Type: text/plain; charset="utf-8" Implement read/write handlers for the SMMU_S_INIT secure-only register. Writing to this register provides a mechanism for software to perform a global invalidation of ALL caches within the SMMU. This includes the IOTLBs and Configuration Caches across all security states. This feature is critical for secure hypervisors like Hafnium, which use it as a final step in their SMMU initialization sequence. It provides a reliable, architecturally defined method to ensure a clean and known-good cache state before enabling translations. Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 33 +++++++++++++++++++++++++++++++++ hw/arm/trace-events | 1 + 2 files changed, 34 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 100caeeb35..432de88610 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -354,6 +354,21 @@ static int smmu_get_ste(SMMUv3State *s, dma_addr_t add= r, STE *buf, =20 } =20 +static void smmuv3_invalidate_all_caches(SMMUv3State *s) +{ + trace_smmuv3_invalidate_all_caches(); + SMMUState *bs =3D &s->smmu_state; + + /* Clear all cached configs including STE and CD */ + if (bs->configs) { + g_hash_table_remove_all(bs->configs); + } + + /* Invalidate all SMMU IOTLB entries */ + smmu_inv_notifiers_all(&s->smmu_state); + smmu_iotlb_inv_all(bs); +} + static SMMUTranslationStatus smmuv3_do_translate(SMMUv3State *s, hwaddr ad= dr, SMMUTransCfg *cfg, SMMUEventInfo *event, @@ -1969,6 +1984,21 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, =20 bank->eventq_irq_cfg2 =3D data; return MEMTX_OK; + case (A_S_INIT & 0xfff): + if (data & R_S_INIT_INV_ALL_MASK) { + int cr0_smmuen =3D smmu_enabled(s, reg_sec_sid); + int s_cr0_smmuen =3D smmuv3_get_cr0ack_smmuen(s, reg_sec_sid); + if (cr0_smmuen || s_cr0_smmuen) { + /* CONSTRAINED UNPREDICTABLE behavior: Ignore this write */ + qemu_log_mask(LOG_GUEST_ERROR, "S_INIT write ignored: " + "CR0.SMMUEN=3D%d or S_CR0.SMMUEN=3D%d is set= \n", + cr0_smmuen, s_cr0_smmuen); + return MEMTX_OK; + } + smmuv3_invalidate_all_caches(s); + } + /* Synchronous emulation: invalidation completed instantly. */ + return MEMTX_OK; default: qemu_log_mask(LOG_UNIMP, "%s Unexpected 32-bit access to 0x%"PRIx64" (WI)\n", @@ -2172,6 +2202,9 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr = offset, case A_EVENTQ_CONS: *data =3D bank->eventq.cons; return MEMTX_OK; + case (A_S_INIT & 0xfff): + *data =3D 0; + return MEMTX_OK; default: *data =3D 0; qemu_log_mask(LOG_UNIMP, diff --git a/hw/arm/trace-events b/hw/arm/trace-events index 434d6abfc2..0e7ad8fee3 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -64,6 +64,7 @@ smmuv3_cmdq_tlbi_s12_vmid(int vmid) "vmid=3D%d" smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu= mr=3D%s" smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu= mr=3D%s" smmuv3_inv_notifiers_iova(const char *name, int asid, int vmid, uint64_t i= ova, uint8_t tg, uint64_t num_pages, int stage) "iommu mr=3D%s asid=3D%d vm= id=3D%d iova=3D0x%"PRIx64" tg=3D%d num_pages=3D0x%"PRIx64" stage=3D%d" +smmuv3_invalidate_all_caches(void) "Invalidate all SMMU caches and TLBs" smmu_reset_exit(void) "" =20 # strongarm.c --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 176028208301837.50780242605106; Sun, 12 Oct 2025 08:14:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xmQ-0002RJ-Ae; Sun, 12 Oct 2025 11:14:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xmG-0002MQ-Tz; Sun, 12 Oct 2025 11:14:32 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xmE-0002X9-Rs; Sun, 12 Oct 2025 11:14:28 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwD31yTPxeto+SorAA--.35253S2; Sun, 12 Oct 2025 23:14:23 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwD3WefOxetoWXhMAA--.2266S3; Sun, 12 Oct 2025 23:14:23 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 17/21] hw/arm/smmuv3: Pass security state to command queue and IRQ logic Date: Sun, 12 Oct 2025 23:14:20 +0800 Message-Id: <20251012151420.4130577-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwD3WefOxetoWXhMAA--.2266S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBcgAAsD Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3GF13AF45XF1ktF1DtF45Awb_yoWfur4Upr 4UK3sxWr1rt3Z3XF9rA3y8uF13J348tr9xtrWjga4fCas8Ar15Xr4vg3WY934DWryxZws3 ZayfGrs8Z3W7Aw7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=162.243.164.118; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmtyylji0my4xnjqumte4.icoremail.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282084405154100 Content-Type: text/plain; charset="utf-8" The command queue and interrupt logic must operate within the correct security context. Handling a command queue in one security state can have side effects, such as interrupts or errors, that need to be processed in another. This requires the IRQ and GERROR logic to be fully aware of the multi-security-state environment. This patch refactors the command queue processing and interrupt handling to be security-state aware. Besides, unlike the command queue, the event queue logic was already updated to be security-state aware in a previous change. The SMMUSecSID is now passed through the relevant functions to ensure that: - Command queue operations are performed on the correct register bank. - Interrupts are triggered and checked against the correct security state's configuration. - Errors from command processing are reported in the correct GERROR register bank. - Architectural access controls, like preventing secure commands from a non-secure queue, are correctly enforced. - As Secure Stage 2 is not yet implemented, commands that target it are now correctly aborted during command queue processing. Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 61 +++++++++++++++++++++++++++++++-------------- hw/arm/trace-events | 2 +- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 432de88610..4ac7a2f3c7 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -46,11 +46,11 @@ * * @irq: irq type * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR) + * @sec_sid: SEC_SID of the bank */ static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, - uint32_t gerror_mask) + uint32_t gerror_mask, SMMUSecSID sec_sid) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); =20 bool pulse =3D false; @@ -87,9 +87,9 @@ static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq ir= q, } } =20 -static void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn) +static void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn, + SMMUSecSID sec_sid) { - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); uint32_t pending =3D bank->gerror ^ bank->gerrorn; uint32_t toggled =3D bank->gerrorn ^ new_gerrorn; @@ -109,7 +109,7 @@ static void smmuv3_write_gerrorn(SMMUv3State *s, uint32= _t new_gerrorn) trace_smmuv3_write_gerrorn(toggled & pending, bank->gerrorn); } =20 -static inline MemTxResult queue_read(SMMUQueue *q, Cmd *cmd) +static inline MemTxResult queue_read(SMMUQueue *q, Cmd *cmd, SMMUSecSID se= c_sid) { dma_addr_t addr =3D Q_CONS_ENTRY(q); MemTxResult ret; @@ -167,7 +167,7 @@ static MemTxResult smmuv3_write_eventq(SMMUv3State *s, = SMMUSecSID sec_sid, } =20 if (!smmuv3_q_empty(q)) { - smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0); + smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0, sec_sid); } return MEMTX_OK; } @@ -263,7 +263,8 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo = *info) info->sid); r =3D smmuv3_write_eventq(s, sec_sid, &evt); if (r !=3D MEMTX_OK) { - smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MAS= K); + smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, + R_GERROR_EVENTQ_ABT_ERR_MASK, sec_sid); } info->recorded =3D true; } @@ -1457,11 +1458,10 @@ static bool smmu_eventq_irq_cfg_writable(SMMUv3Stat= e *s, SMMUSecSID sec_sid) return smmu_irq_ctl_evtq_irqen_disabled(s, sec_sid); } =20 -static int smmuv3_cmdq_consume(SMMUv3State *s) +static int smmuv3_cmdq_consume(SMMUv3State *s, SMMUSecSID sec_sid) { SMMUState *bs =3D ARM_SMMU(s); SMMUCmdError cmd_error =3D SMMU_CERROR_NONE; - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); SMMUQueue *q =3D &bank->cmdq; SMMUCommandType type =3D 0; @@ -1480,14 +1480,14 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) uint32_t pending =3D bank->gerror ^ bank->gerrorn; Cmd cmd; =20 - trace_smmuv3_cmdq_consume(Q_PROD(q), Q_CONS(q), + trace_smmuv3_cmdq_consume(sec_sid, Q_PROD(q), Q_CONS(q), Q_PROD_WRAP(q), Q_CONS_WRAP(q)); =20 if (FIELD_EX32(pending, GERROR, CMDQ_ERR)) { break; } =20 - if (queue_read(q, &cmd) !=3D MEMTX_OK) { + if (queue_read(q, &cmd, sec_sid) !=3D MEMTX_OK) { cmd_error =3D SMMU_CERROR_ABT; break; } @@ -1500,7 +1500,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) switch (type) { case SMMU_CMD_SYNC: if (CMD_SYNC_CS(&cmd) & CMD_SYNC_SIG_IRQ) { - smmuv3_trigger_irq(s, SMMU_IRQ_CMD_SYNC, 0); + smmuv3_trigger_irq(s, SMMU_IRQ_CMD_SYNC, 0, sec_sid); } break; case SMMU_CMD_PREFETCH_CONFIG: @@ -1512,6 +1512,11 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) SMMUDevice *sdev =3D smmu_find_sdev(bs, sid); =20 if (CMD_SSEC(&cmd)) { + if (sec_sid !=3D SMMU_SEC_SID_S) { + /* Secure Stream with Non-Secure command */ + cmd_error =3D SMMU_CERROR_ILL; + break; + } cmd_error =3D SMMU_CERROR_ILL; break; } @@ -1532,6 +1537,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) SMMUSIDRange sid_range; =20 if (CMD_SSEC(&cmd)) { + if (sec_sid !=3D SMMU_SEC_SID_S) { + cmd_error =3D SMMU_CERROR_ILL; + break; + } cmd_error =3D SMMU_CERROR_ILL; break; } @@ -1551,6 +1560,10 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) SMMUDevice *sdev =3D smmu_find_sdev(bs, sid); =20 if (CMD_SSEC(&cmd)) { + if (sec_sid !=3D SMMU_SEC_SID_S) { + cmd_error =3D SMMU_CERROR_ILL; + break; + } cmd_error =3D SMMU_CERROR_ILL; break; } @@ -1618,7 +1631,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) cmd_error =3D SMMU_CERROR_ILL; break; } - smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1, SMMU_SEC_SID_NS); + smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1, sec_sid); break; case SMMU_CMD_TLBI_S12_VMALL: { @@ -1628,6 +1641,11 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) cmd_error =3D SMMU_CERROR_ILL; break; } + /* Secure Stage 2 isn't supported for now */ + if (sec_sid !=3D SMMU_SEC_SID_NS) { + cmd_error =3D SMMU_CERROR_ABT; + break; + } =20 trace_smmuv3_cmdq_tlbi_s12_vmid(vmid); smmu_inv_notifiers_all(&s->smmu_state); @@ -1639,11 +1657,16 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) cmd_error =3D SMMU_CERROR_ILL; break; } + + if (sec_sid !=3D SMMU_SEC_SID_NS) { + cmd_error =3D SMMU_CERROR_ABT; + break; + } /* * As currently only either s1 or s2 are supported * we can reuse same function for s2. */ - smmuv3_range_inval(bs, &cmd, SMMU_STAGE_2, SMMU_SEC_SID_NS); + smmuv3_range_inval(bs, &cmd, SMMU_STAGE_2, sec_sid); break; case SMMU_CMD_TLBI_EL3_ALL: case SMMU_CMD_TLBI_EL3_VA: @@ -1680,7 +1703,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) if (cmd_error) { trace_smmuv3_cmdq_consume_error(smmu_cmd_string(type), cmd_error); smmu_write_cmdq_err(s, cmd_error, sec_sid); - smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_CMDQ_ERR_MASK); + smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_CMDQ_ERR_MASK, sec= _sid); } =20 trace_smmuv3_cmdq_consume_out(Q_PROD(q), Q_CONS(q), @@ -1772,7 +1795,7 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr= offset, bank->cr[0] =3D data; bank->cr0ack =3D data & ~SMMU_CR0_RESERVED; /* in case the command queue has been enabled */ - smmuv3_cmdq_consume(s); + smmuv3_cmdq_consume(s, reg_sec_sid); return MEMTX_OK; case A_CR1: bank->cr[1] =3D data; @@ -1792,12 +1815,12 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, bank->irq_ctrl =3D data; return MEMTX_OK; case A_GERRORN: - smmuv3_write_gerrorn(s, data); + smmuv3_write_gerrorn(s, data, reg_sec_sid); /* * By acknowledging the CMDQ_ERR, SW may notify cmds can * be processed again */ - smmuv3_cmdq_consume(s); + smmuv3_cmdq_consume(s, reg_sec_sid); return MEMTX_OK; case A_GERROR_IRQ_CFG0: /* 64b */ if (!smmu_gerror_irq_cfg_writable(s, reg_sec_sid)) { @@ -1899,7 +1922,7 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr= offset, return MEMTX_OK; case A_CMDQ_PROD: bank->cmdq.prod =3D data; - smmuv3_cmdq_consume(s); + smmuv3_cmdq_consume(s, reg_sec_sid); return MEMTX_OK; case A_CMDQ_CONS: if (!smmu_cmdqen_disabled(s, reg_sec_sid)) { diff --git a/hw/arm/trace-events b/hw/arm/trace-events index 0e7ad8fee3..697e0d84f3 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -35,7 +35,7 @@ smmuv3_trigger_irq(int irq) "irq=3D%d" smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=3D0x%x, ne= w GERROR=3D0x%x" smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=3D0x%x, new = GERRORN=3D0x%x" smmuv3_unhandled_cmd(uint32_t type) "Unhandled command type=3D%d" -smmuv3_cmdq_consume(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8= _t cons_wrap) "prod=3D%d cons=3D%d prod.wrap=3D%d cons.wrap=3D%d" +smmuv3_cmdq_consume(int sec_sid, uint32_t prod, uint32_t cons, uint8_t pro= d_wrap, uint8_t cons_wrap) "sec_sid=3D%d prod=3D%d cons=3D%d prod.wrap=3D%d= cons.wrap=3D%d" smmuv3_cmdq_opcode(const char *opcode) "<--- %s" smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, u= int8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d " smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error = on %s command execution: %d" --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 176028212247466.64401757832889; Sun, 12 Oct 2025 08:15:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xml-0002uL-NO; Sun, 12 Oct 2025 11:14:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xmh-0002kk-RL; Sun, 12 Oct 2025 11:14:55 -0400 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net ([209.97.181.73]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xme-0002Yd-SK; Sun, 12 Oct 2025 11:14:55 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwCHj5vnxetoSFigAA--.19S2; Sun, 12 Oct 2025 23:14:47 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwBHq+jkxetoYXhMAA--.3042S3; Sun, 12 Oct 2025 23:14:44 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 18/21] hw/arm/smmuv3: Harden security checks in MMIO handlers Date: Sun, 12 Oct 2025 23:14:37 +0800 Message-Id: <20251012151437.4130770-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwBHq+jkxetoYXhMAA--.3042S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBdAAAsF Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxGFykuF15Gw4xWrW5AFWfAFb_yoWrWF45pr 4vgryYgr4DKF13XF4fJw4DA3WrCayvqrZxCrZxG3yUAayUGr4rJr48Ca4Yqr1DGry7Zws7 GFySyrWfur1jy3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=209.97.181.73; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmja5ljk3lje4ms43mwaa.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282124228154100 Content-Type: text/plain; charset="utf-8" This patch hardens the security validation within the main MMIO dispatcher functions (smmu_read_mmio and smmu_write_mmio). First, accesses to the secure register space are now correctly gated by whether the SECURE_IMPL feature is enabled in the model. This prevents guest software from accessing the secure programming interface when it is disabled, though some registers are exempt from this check as per the architecture. Second, the check for the input stream's security is made more robust. It now validates not only the legacy MemTxAttrs.secure bit, but also the .space field. This brings the SMMU's handling of security spaces into full alignment with the PE. Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 4ac7a2f3c7..c9c742c80b 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1458,6 +1458,12 @@ static bool smmu_eventq_irq_cfg_writable(SMMUv3State= *s, SMMUSecSID sec_sid) return smmu_irq_ctl_evtq_irqen_disabled(s, sec_sid); } =20 +/* Check if the SMMU hardware itself implements secure state features */ +static inline bool smmu_hw_secure_implemented(SMMUv3State *s) +{ + return FIELD_EX32(s->bank[SMMU_SEC_SID_S].idr[1], S_IDR1, SECURE_IMPL); +} + static int smmuv3_cmdq_consume(SMMUv3State *s, SMMUSecSID sec_sid) { SMMUState *bs =3D ARM_SMMU(s); @@ -1712,6 +1718,55 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, SMMUS= ecSID sec_sid) return 0; } =20 +/* + * Check if a register is exempt from the secure implementation check. + * + * The SMMU architecture specifies that certain secure registers, such as + * the secure Event Queue IRQ configuration registers, must be accessible + * even if the full secure hardware is not implemented. This function + * identifies those registers. + * + * Returns true if the register is exempt, false otherwise. + */ +static bool is_secure_impl_exempt_reg(hwaddr offset) +{ + switch (offset) { + case A_S_EVENTQ_IRQ_CFG0: + case A_S_EVENTQ_IRQ_CFG1: + case A_S_EVENTQ_IRQ_CFG2: + return true; + default: + return false; + } +} + +/* Helper function for Secure register access validation */ +static bool smmu_check_secure_access(SMMUv3State *s, MemTxAttrs attrs, + hwaddr offset, bool is_read) +{ /* Check if the access is secure */ + if (!(attrs.space =3D=3D ARMSS_Secure || + attrs.secure =3D=3D 1)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Non-secure %s attempt at offset 0x%" PRIx64 " (%s)\n", + __func__, is_read ? "read" : "write", offset, + is_read ? "RAZ" : "WI"); + return false; + } + + /* + * Check if the secure state is implemented. Some registers are exempt= ed + * from this check. + */ + if (!is_secure_impl_exempt_reg(offset) && !smmu_hw_secure_implemented(= s)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Secure %s attempt at offset 0x%" PRIx64 ". But Secure sta= te " + "is not implemented (RES0)\n", + __func__, is_read ? "read" : "write", offset); + return false; + } + return true; +} + static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset, uint64_t data, MemTxAttrs attrs, SMMUSecSID reg_sec_sid) @@ -2058,6 +2113,10 @@ static MemTxResult smmu_write_mmio(void *opaque, hwa= ddr offset, uint64_t data, * statement to handle those specific security states. */ if (offset >=3D SMMU_SECURE_REG_START) { + if (!smmu_check_secure_access(s, attrs, offset, false)) { + trace_smmuv3_write_mmio(offset, data, size, MEMTX_OK); + return MEMTX_OK; + } reg_sec_sid =3D SMMU_SEC_SID_S; } =20 @@ -2248,6 +2307,11 @@ static MemTxResult smmu_read_mmio(void *opaque, hwad= dr offset, uint64_t *data, offset &=3D ~0x10000; SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; if (offset >=3D SMMU_SECURE_REG_START) { + if (!smmu_check_secure_access(s, attrs, offset, true)) { + *data =3D 0; + trace_smmuv3_read_mmio(offset, *data, size, MEMTX_OK); + return MEMTX_OK; + } reg_sec_sid =3D SMMU_SEC_SID_S; } =20 --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760282137754248.9313012765558; Sun, 12 Oct 2025 08:15:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xn0-0003Mf-Kt; Sun, 12 Oct 2025 11:15:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xmz-0003HH-3Q; Sun, 12 Oct 2025 11:15:13 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xmw-0002kc-IE; Sun, 12 Oct 2025 11:15:12 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwCHjZn5xetotligAA--.81S2; Sun, 12 Oct 2025 23:15:05 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwD3Wef4xetoZnhMAA--.2267S3; Sun, 12 Oct 2025 23:15:04 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 19/21] hw/arm/smmuv3: Use iommu_index to represent the security context Date: Sun, 12 Oct 2025 23:15:01 +0800 Message-Id: <20251012151501.4131026-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwD3Wef4xetoZnhMAA--.2267S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBdgAAsH Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxZF1xWryxXr4fAFy3Aw4Utwb_yoW5CFWxpr 4UGa93Kws8GF1fZF1fJa1UZF4a9397GF43XrZ3Kan5Aw18Awn7XFZ2kFyYgryDAFWUAw42 vay0ka9rWa1qyrJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282149212158500 Content-Type: text/plain; charset="utf-8" The Arm SMMUv3 architecture uses a SEC_SID (Secure StreamID) to select the programming interface. To support future extensions like RME, which defines four security states (Non-secure, Secure, Realm, and Root), the QEMU model must cleanly separate these contexts for all operations. This commit leverages the generic iommu_index to represent this security context. The core IOMMU layer now uses the SMMU's .attrs_to_index callback to map a transaction's ARMSecuritySpace attribute to the corresponding iommu_index. This index is then passed down to smmuv3_translate and used throughout the model to select the correct register bank and processing logic. This makes the iommu_index the clear QEMU equivalent of the architectural SEC_SID, cleanly separating the contexts for all subsequent lookups. Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index c9c742c80b..b44859540f 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1080,6 +1080,38 @@ static void smmuv3_fixup_event(SMMUEventInfo *event,= hwaddr iova) } } =20 +static SMMUSecSID smmuv3_attrs_to_sec_sid(MemTxAttrs attrs) +{ + switch (attrs.space) { + case ARMSS_Secure: + return SMMU_SEC_SID_S; + case ARMSS_NonSecure: + default: + return SMMU_SEC_SID_NS; + } +} + +/* + * ARM IOMMU index mapping (implements SEC_SID from ARM SMMU): + * iommu_idx =3D 0: Non-secure transactions + * iommu_idx =3D 1: Secure transactions + * + * The iommu_idx parameter effectively implements the SEC_SID + * (Security Stream ID) attribute from the ARM SMMU architecture specifica= tion, + * which allows the SMMU to differentiate between different security state + * transactions at the hardware level. + */ +static int smmuv3_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attr= s) +{ + return (int)smmuv3_attrs_to_sec_sid(attrs); +} + +static int smmuv3_num_indexes(IOMMUMemoryRegion *iommu) +{ + /* Support 2 IOMMU indexes for now: NS/S */ + return SMMU_SEC_SID_NUM; +} + /* Entry point to SMMU, does everything. */ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr, IOMMUAccessFlags flag, int iommu_idx) @@ -1087,7 +1119,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegi= on *mr, hwaddr addr, SMMUDevice *sdev =3D container_of(mr, SMMUDevice, iommu); SMMUv3State *s =3D sdev->smmu; uint32_t sid =3D smmu_get_sid(sdev); - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUSecSID sec_sid =3D iommu_idx; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); SMMUEventInfo event =3D {.type =3D SMMU_EVT_NONE, .sid =3D sid, @@ -2540,6 +2572,8 @@ static void smmuv3_iommu_memory_region_class_init(Obj= ectClass *klass, =20 imrc->translate =3D smmuv3_translate; imrc->notify_flag_changed =3D smmuv3_notify_flag_changed; + imrc->attrs_to_index =3D smmuv3_attrs_to_index; + imrc->num_indexes =3D smmuv3_num_indexes; } =20 static const TypeInfo smmuv3_type_info =3D { --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760282167105922.6927601553245; Sun, 12 Oct 2025 08:16:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xnm-00046d-OU; Sun, 12 Oct 2025 11:16:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xnf-00042C-1C; Sun, 12 Oct 2025 11:16:01 -0400 Received: from zg8tmtyylji0my4xnjeumjiw.icoremail.net ([162.243.161.220]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xnY-0002nm-QW; Sun, 12 Oct 2025 11:15:54 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with SMTP id AQAAfwDnxyQhxutoyysrAA--.34862S2; Sun, 12 Oct 2025 23:15:45 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwBHq+ggxutocXhMAA--.3043S3; Sun, 12 Oct 2025 23:15:45 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 20/21] hw/arm/smmuv3: Initialize the secure register bank Date: Sun, 12 Oct 2025 23:15:42 +0800 Message-Id: <20251012151542.4131398-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwBHq+ggxutocXhMAA--.3043S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBeAAAsJ Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7tFyDZF1Dur45ZrWrCrWDCFg_yoW8Gr18pa 9rJwn8Kry5K3WSga9xJw48AF1Iqwsaqr1DZry7KF13A3W5Jr97XrWrKa4rKrZY9rZ8CF4U WF1S9rs5ZwsIvaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=162.243.161.220; envelope-from=tangtao1634@phytium.com.cn; helo=zg8tmtyylji0my4xnjeumjiw.icoremail.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282168994154100 Content-Type: text/plain; charset="utf-8" Initialize the secure register bank (SMMU_SEC_SID_S) with sane default values during the SMMU's reset sequence. This change ensures that key fields, such as the secure ID registers, GBPA reset value, and queue entry sizes, are set to a known-good state. The SECURE_IMPL attribute of the S_IDR1 register will be introduced later via device properties. This is a necessary step to prevent undefined behavior when secure SMMU features are subsequently enabled and used by software. Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index b44859540f..0b366895ec 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -331,6 +331,15 @@ static void smmuv3_init_regs(SMMUv3State *s) bk->gerrorn =3D 0; s->statusr =3D 0; bk->gbpa =3D SMMU_GBPA_RESET_VAL; + + /* Initialize Secure bank */ + SMMUv3RegBank *sbk =3D &s->bank[SMMU_SEC_SID_S]; + + memset(sbk->idr, 0, sizeof(sbk->idr)); + sbk->idr[1] =3D FIELD_DP32(sbk->idr[1], S_IDR1, S_SIDSIZE, SMMU_IDR1_S= IDSIZE); + sbk->gbpa =3D SMMU_GBPA_RESET_VAL; + sbk->cmdq.entry_size =3D sizeof(struct Cmd); + sbk->eventq.entry_size =3D sizeof(struct Evt); } =20 static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, --=20 2.34.1 From nobody Fri Nov 14 18:24:04 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760282205414465.013805127354; Sun, 12 Oct 2025 08:16:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xoG-0004hY-Bc; Sun, 12 Oct 2025 11:16:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v7xoE-0004gy-SW; Sun, 12 Oct 2025 11:16:30 -0400 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v7xoC-0002pR-Iu; Sun, 12 Oct 2025 11:16:30 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwCnr5tIxutobFqgAA--.6S2; Sun, 12 Oct 2025 23:16:24 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXO+lHxutohHhMAA--.1378S3; Sun, 12 Oct 2025 23:16:23 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jean-Philippe Brucker , Mostafa Saleh , Tao Tang Subject: [RFC v3 21/21] hw/arm/smmuv3: Add secure migration and enable secure state Date: Sun, 12 Oct 2025 23:16:11 +0800 Message-Id: <20251012151611.4131627-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> References: <20251012150701.4127034-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXO+lHxutohHhMAA--.1378S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQABBWjqskUBewAAsK Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxKw18uF1DKFW3XF4kKw4rZrb_yoW7ZF1fpr s8G3Z8GryDGF4fur4fJw48CFs5CrWfGF4YkrZrCa9aya1kJw42qrn2yayfW3s5JrWUXa17 uF109FZrXw4UArJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1760282216249158501 Introduce a bool secure_impl field to SMMUv3State and expose it as a secure-impl device property. The introduction of this property is the culminating step that activates the entire secure access data path, tying together all previously merged logic to provide full support for secure state accesses. Add live migration support for the SMMUv3 secure register bank. To correctly migrate the secure state, the migration logic must know if the secure functionality is enabled. To facilitate this, a bool secure_impl field is introduced and exposed as the secure-impl device property. This property is introduced at the point it is first required=E2=80=94for migration=E2=80=94and serves as the final piece of the= series. The introduction of this property also completes and activates the entire secure access data path, tying together all previously merged logic to provide full support for secure state accesses. Usage: -global arm-smmuv3,secure-impl=3Dtrue When this property is enabled, the capability is advertised to the guest via the S_IDR1.SECURE_IMPL bit. The migration is implemented as follows: - A new vmstate_smmuv3_secure_bank, referenced by the smmuv3/bank_s subsection, serializes the secure bank's registers and queues. - A companion smmuv3/gbpa_secure subsection mirrors the non-secure GBPA handling, migrating the register only if its value diverges from the reset default. Signed-off-by: Tao Tang --- hw/arm/smmuv3.c | 75 +++++++++++++++++++++++++++++++++++++++++ include/hw/arm/smmuv3.h | 1 + 2 files changed, 76 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 0b366895ec..ce41a12a36 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -337,6 +337,7 @@ static void smmuv3_init_regs(SMMUv3State *s) =20 memset(sbk->idr, 0, sizeof(sbk->idr)); sbk->idr[1] =3D FIELD_DP32(sbk->idr[1], S_IDR1, S_SIDSIZE, SMMU_IDR1_S= IDSIZE); + sbk->idr[1] =3D FIELD_DP32(sbk->idr[1], S_IDR1, SECURE_IMPL, s->secure= _impl); sbk->gbpa =3D SMMU_GBPA_RESET_VAL; sbk->cmdq.entry_size =3D sizeof(struct Cmd); sbk->eventq.entry_size =3D sizeof(struct Evt); @@ -2452,6 +2453,53 @@ static const VMStateDescription vmstate_smmuv3_queue= =3D { }, }; =20 +static const VMStateDescription vmstate_smmuv3_secure_bank =3D { + .name =3D "smmuv3_secure_bank", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(features, SMMUv3RegBank), + VMSTATE_UINT8(sid_split, SMMUv3RegBank), + VMSTATE_UINT32_ARRAY(cr, SMMUv3RegBank, 3), + VMSTATE_UINT32(cr0ack, SMMUv3RegBank), + VMSTATE_UINT32(irq_ctrl, SMMUv3RegBank), + VMSTATE_UINT32(gerror, SMMUv3RegBank), + VMSTATE_UINT32(gerrorn, SMMUv3RegBank), + VMSTATE_UINT64(gerror_irq_cfg0, SMMUv3RegBank), + VMSTATE_UINT32(gerror_irq_cfg1, SMMUv3RegBank), + VMSTATE_UINT32(gerror_irq_cfg2, SMMUv3RegBank), + VMSTATE_UINT64(strtab_base, SMMUv3RegBank), + VMSTATE_UINT32(strtab_base_cfg, SMMUv3RegBank), + VMSTATE_UINT64(eventq_irq_cfg0, SMMUv3RegBank), + VMSTATE_UINT32(eventq_irq_cfg1, SMMUv3RegBank), + VMSTATE_UINT32(eventq_irq_cfg2, SMMUv3RegBank), + VMSTATE_STRUCT(cmdq, SMMUv3RegBank, 0, + vmstate_smmuv3_queue, SMMUQueue), + VMSTATE_STRUCT(eventq, SMMUv3RegBank, 0, + vmstate_smmuv3_queue, SMMUQueue), + VMSTATE_END_OF_LIST(), + }, +}; + +static bool smmuv3_secure_bank_needed(void *opaque) +{ + SMMUv3State *s =3D opaque; + + return s->secure_impl; +} + +static const VMStateDescription vmstate_smmuv3_bank_s =3D { + .name =3D "smmuv3/bank_s", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D smmuv3_secure_bank_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_STRUCT(bank[SMMU_SEC_SID_S], SMMUv3State, 0, + vmstate_smmuv3_secure_bank, SMMUv3RegBank), + VMSTATE_END_OF_LIST(), + }, +}; + static bool smmuv3_gbpa_needed(void *opaque) { SMMUv3State *s =3D opaque; @@ -2472,6 +2520,25 @@ static const VMStateDescription vmstate_gbpa =3D { } }; =20 +static bool smmuv3_gbpa_secure_needed(void *opaque) +{ + SMMUv3State *s =3D opaque; + + return s->secure_impl && + s->bank[SMMU_SEC_SID_S].gbpa !=3D SMMU_GBPA_RESET_VAL; +} + +static const VMStateDescription vmstate_gbpa_secure =3D { + .name =3D "smmuv3/gbpa_secure", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D smmuv3_gbpa_secure_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32(bank[SMMU_SEC_SID_S].gbpa, SMMUv3State), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_smmuv3 =3D { .name =3D "smmuv3", .version_id =3D 1, @@ -2506,6 +2573,8 @@ static const VMStateDescription vmstate_smmuv3 =3D { }, .subsections =3D (const VMStateDescription * const []) { &vmstate_gbpa, + &vmstate_smmuv3_bank_s, + &vmstate_gbpa_secure, NULL } }; @@ -2519,6 +2588,12 @@ static const Property smmuv3_properties[] =3D { * Defaults to stage 1 */ DEFINE_PROP_STRING("stage", SMMUv3State, stage), + /* + * SECURE_IMPL field in S_IDR1 register. + * Indicates whether secure state is implemented. + * Defaults to false (0) + */ + DEFINE_PROP_BOOL("secure-impl", SMMUv3State, secure_impl, false), }; =20 static void smmuv3_instance_init(Object *obj) diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index e9012fcdb0..8fec3f8edb 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -69,6 +69,7 @@ struct SMMUv3State { qemu_irq irq[4]; QemuMutex mutex; char *stage; + bool secure_impl; }; =20 typedef enum { --=20 2.34.1