From nobody Sun Apr 12 04:28:46 2026 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 1771669132032279.2429458093811; Sat, 21 Feb 2026 02:18:52 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vtk4U-0002u0-CL; Sat, 21 Feb 2026 05:18:46 -0500 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 1vtk4O-0002f4-2A; Sat, 21 Feb 2026 05:18:40 -0500 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vtk4L-0002aj-Hh; Sat, 21 Feb 2026 05:18:39 -0500 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwC3vJh6hplpzq9VBw--.4496S2; Sat, 21 Feb 2026 18:18:34 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXLet4hplpfE4cAA--.34240S3; Sat, 21 Feb 2026 18:18:32 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell , "Michael S . Tsirkin" , Marcel Apfelbaum Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Mostafa Saleh , Chao Liu , Tao Tang Subject: [RFC v4 24/31] hw/arm/smmuv3: Determine register bank from MMIO offset Date: Sat, 21 Feb 2026 18:18:29 +0800 Message-Id: <20260221101830.2996354-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260221100250.2976287-1-tangtao1634@phytium.com.cn> References: <20260221100250.2976287-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXLet4hplpfE4cAA--.34240S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQANBWmYzyUARQAAsX Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3AryfCry5tr1rCr1UuF1Dtrb_yoWxJr1xpr Z8XF1Sgrn8Ka1SqwsxJa1UC3W8Cwn7Kr1akrnxKryDu3yIywn7JayvyryfuryDury7Zrs8 trW5Gr47WrWqy3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: qemu development 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: 1771669133043158500 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 3 security states (Non-secure, Secure, Realm) 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 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 handling */ } will need to be expanded. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 57 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 9c09ea0716e..d81485a6a46 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1781,12 +1781,13 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Erro= r **errp, SMMUSecSID sec_sid) } =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 */ @@ -1851,13 +1852,14 @@ 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) { Error *local_err =3D NULL; - 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; @@ -2094,16 +2096,25 @@ static MemTxResult smmu_write_mmio(void *opaque, hw= addr offset, uint64_t data, SMMUState *sys =3D opaque; SMMUv3State *s =3D ARM_SMMUV3(sys); MemTxResult r; + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; =20 /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ offset &=3D ~0x10000; =20 + /* + * Realm and Non-secure share the same page-local offset layout; Secur= e uses + * the same layout but is mapped starting at 0x8000(SMMU_SECURE_REG_ST= ART) + */ + 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; @@ -2115,12 +2126,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)) { @@ -2149,17 +2161,22 @@ 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); + *data =3D smmuv3_idreg(reg_offset - A_IDREGS); return MEMTX_OK; case A_IDR0 ... A_IDR5: - *data =3D bank->idr[(offset - A_IDR0) / 4]; + if (reg_sec_sid =3D=3D SMMU_SEC_SID_S) { + g_assert((reg_offset - A_IDR0) / 4 < 5); + } + + *data =3D bank->idr[(reg_offset - A_IDR0) / 4]; return MEMTX_OK; case A_IIDR: *data =3D s->iidr; @@ -2275,16 +2292,20 @@ static MemTxResult smmu_read_mmio(void *opaque, hwa= ddr offset, uint64_t *data, SMMUState *sys =3D opaque; SMMUv3State *s =3D ARM_SMMUV3(sys); MemTxResult r; + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; =20 /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ offset &=3D ~0x10000; + 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