From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638304660423.80660988287343; Thu, 13 Aug 2026 09:25:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYED-0007yw-TL; Thu, 13 Aug 2026 12:24:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYE9-0007u6-KH; Thu, 13 Aug 2026 12:24:21 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYE7-0000WQ-BZ; Thu, 13 Aug 2026 12:24:21 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwDX16+v731q5U_mAA--.5002S2; Fri, 14 Aug 2026 00:24:15 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwjnOq731q3SwjAA--.59176S3; Fri, 14 Aug 2026 00:24: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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 01/28] hw/arm/smmuv3: Introduce secure registers Date: Fri, 14 Aug 2026 00:24:06 +0800 Message-Id: <20260813162410.2805113-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwjnOq731q3SwjAA--.59176S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HjgAAsZ Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxWr45uF17Zw4xCFWUKr1rJFb_yoW5tw43pF 4Iyr1rG3yDWF42vw1fGa1UAF13Crs3Aa4xJFZFkr129a4fWryayrW8Ka4fGr1kXFn5ZF1U GFnFv340g34Syr7anT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638308156158500 Content-Type: text/plain; charset="utf-8" The Arm SMMUv3 architecture defines a set of registers for managing Secure transactions and contexts. This patch introduces the definitions for these secure registers within the SMMUv3 device model internal header. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Reviewed-by: Mostafa Saleh Link: https://lore.kernel.org/qemu-devel/759ec110-365f-488b-802d-c7bb1efe30= bc@redhat.com/ Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- include/hw/arm/smmuv3-common.h | 71 +++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h index 4609975edf9..ec442a85586 100644 --- a/include/hw/arm/smmuv3-common.h +++ b/include/hw/arm/smmuv3-common.h @@ -269,7 +269,7 @@ REG32(CD_5, 20) ((sel) ? ((cd)->word[4] =3D FIELD_DP32((cd)->word[4], CD_4, NSCFG1, (v= ))) : \ ((cd)->word[2] =3D FIELD_DP32((cd)->word[2], CD_2, NSCFG0, (v= )))) =20 -/* MMIO Registers */ +/* MMIO Registers. Shared by Non-secure/Realm/Root states. */ =20 REG32(IDR0, 0x0) FIELD(IDR0, S2P, 0 , 1) @@ -353,6 +353,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) @@ -411,6 +412,74 @@ 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) + FIELD(S_IDR0, MSI, 13, 1) + FIELD(S_IDR0, STALL_MODEL, 24, 2) +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) + /* Commands */ =20 typedef enum SMMUCommandType { --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638359393112.17496642393269; Thu, 13 Aug 2026 09:25:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEE-0007zJ-Fl; Thu, 13 Aug 2026 12:24:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEC-0007xw-Dm; Thu, 13 Aug 2026 12:24:24 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYE7-0000WR-BW; Thu, 13 Aug 2026 12:24:24 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwCXLlOw731q_xpvAw--.15742S2; Fri, 14 Aug 2026 00:24:16 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwjnOq731q3SwjAA--.59176S4; Fri, 14 Aug 2026 00:24:12 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 02/28] hw/arm/smmuv3: Introduce banked registers for SMMUv3 state Date: Fri, 14 Aug 2026 00:24:07 +0800 Message-Id: <20260813162410.2805113-2-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwjnOq731q3SwjAA--.59176S4 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HjgABsY Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoWDCryfZFyUZF4ktr15Jw1DKFg_yoWrCrWrJo W2yr4qqw4DZw4vka48uFn5JF18tFW8Cw4qva1YqrWa9FsrKw45Kry8trs8CFyakF45XrZ7 Cw4xu3yrXFWIvFn5n29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7KY7ZEXasCq-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=lists1p.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, 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: 1786638362189158500 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 Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Reviewed-by: Mostafa Saleh Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3-accel.c | 67 ++++--- hw/arm/smmuv3-internal.h | 24 ++- hw/arm/smmuv3.c | 374 +++++++++++++++++++---------------- hw/arm/tegra241-cmdqv.c | 6 +- include/hw/arm/smmu-common.h | 6 + include/hw/arm/smmuv3.h | 30 ++- 6 files changed, 295 insertions(+), 212 deletions(-) diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 91aca1aa14e..3ff3da66acd 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -41,6 +41,7 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, struct iommu_hw_info_arm_smmuv3 *in= fo) { SMMUv3AccelState *accel =3D s->s_accel; + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); =20 /* * Return if 'auto' was not set for any accel SMMUv3 property, or @@ -55,23 +56,23 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s, } =20 if (s->ats =3D=3D ON_OFF_AUTO_AUTO) { - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, ATS, - FIELD_EX32(info->idr[0], IDR0, ATS)); + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, ATS, + FIELD_EX32(info->idr[0], IDR0, ATS)); } =20 if (s->ril =3D=3D ON_OFF_AUTO_AUTO) { - s->idr[3] =3D FIELD_DP32(s->idr[3], IDR3, RIL, - FIELD_EX32(info->idr[3], IDR3, RIL)); + bank->idr[3] =3D FIELD_DP32(bank->idr[3], IDR3, RIL, + FIELD_EX32(info->idr[3], IDR3, RIL)); } =20 if (s->ssidsize =3D=3D SSID_SIZE_MODE_AUTO) { - s->idr[1] =3D FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, - FIELD_EX32(info->idr[1], IDR1, SSIDSIZE)); + bank->idr[1] =3D FIELD_DP32(bank->idr[1], IDR1, SSIDSIZE, + FIELD_EX32(info->idr[1], IDR1, SSIDSIZE)= ); } =20 if (s->oas =3D=3D OAS_MODE_AUTO) { - s->idr[5] =3D FIELD_DP32(s->idr[5], IDR5, OAS, - FIELD_EX32(info->idr[5], IDR5, OAS)); + bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, OAS, + FIELD_EX32(info->idr[5], IDR5, OAS)); } =20 accel->auto_finalised =3D true; @@ -82,21 +83,22 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s, struct iommu_hw_info_arm_smmuv3 *info, Error **errp) { + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); smmuv3_accel_auto_finalise(s, info); =20 /* QEMU SMMUv3 supports both linear and 2-level stream tables */ if (FIELD_EX32(info->idr[0], IDR0, STLEVEL) !=3D - FIELD_EX32(s->idr[0], IDR0, STLEVEL)) { + FIELD_EX32(bank->idr[0], IDR0, STLEVEL)) { error_setg(errp, "Host SMMUv3 Stream Table format mismatch " "(host STLEVEL=3D%u, QEMU STLEVEL=3D%u)", FIELD_EX32(info->idr[0], IDR0, STLEVEL), - FIELD_EX32(s->idr[0], IDR0, STLEVEL)); + FIELD_EX32(bank->idr[0], IDR0, STLEVEL)); return false; } =20 /* QEMU SMMUv3 supports only little-endian translation table walks */ if (FIELD_EX32(info->idr[0], IDR0, TTENDIAN) > - FIELD_EX32(s->idr[0], IDR0, TTENDIAN)) { + FIELD_EX32(bank->idr[0], IDR0, TTENDIAN)) { error_setg(errp, "Host SMMUv3 doesn't support Little-endian " "translation table"); return false; @@ -104,7 +106,7 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s, =20 /* QEMU SMMUv3 supports only AArch64 translation table format */ if (FIELD_EX32(info->idr[0], IDR0, TTF) < - FIELD_EX32(s->idr[0], IDR0, TTF)) { + FIELD_EX32(bank->idr[0], IDR0, TTF)) { error_setg(errp, "Host SMMUv3 doesn't support AArch64 translation " "table format"); return false; @@ -112,59 +114,59 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s, =20 /* QEMU SMMUv3 supports SIDSIZE 16 */ if (FIELD_EX32(info->idr[1], IDR1, SIDSIZE) < - FIELD_EX32(s->idr[1], IDR1, SIDSIZE)) { + FIELD_EX32(bank->idr[1], IDR1, SIDSIZE)) { error_setg(errp, "Host SMMUv3 SIDSIZE not compatible " "(host=3D%u, QEMU=3D%u)", FIELD_EX32(info->idr[1], IDR1, SIDSIZE), - FIELD_EX32(s->idr[1], IDR1, SIDSIZE)); + FIELD_EX32(bank->idr[1], IDR1, SIDSIZE)); return false; } =20 /* Check SSIDSIZE value opted-in is compatible with Host SMMUv3 SSIDSI= ZE */ if (FIELD_EX32(info->idr[1], IDR1, SSIDSIZE) < - FIELD_EX32(s->idr[1], IDR1, SSIDSIZE)) { + FIELD_EX32(bank->idr[1], IDR1, SSIDSIZE)) { error_setg(errp, "Host SMMUv3 SSIDSIZE not compatible " "(host=3D%u, QEMU=3D%u)", FIELD_EX32(info->idr[1], IDR1, SSIDSIZE), - FIELD_EX32(s->idr[1], IDR1, SSIDSIZE)); + FIELD_EX32(bank->idr[1], IDR1, SSIDSIZE)); return false; } =20 /* User can disable QEMU SMMUv3 Range Invalidation support */ if (FIELD_EX32(info->idr[3], IDR3, RIL) < - FIELD_EX32(s->idr[3], IDR3, RIL)) { + FIELD_EX32(bank->idr[3], IDR3, RIL)) { error_setg(errp, "Host SMMUv3 doesn't support Range Invalidation"); return false; } /* Check OAS value opted is compatible with Host SMMUv3 IPA */ if (FIELD_EX32(info->idr[5], IDR5, OAS) < - FIELD_EX32(s->idr[5], IDR5, OAS)) { + FIELD_EX32(bank->idr[5], IDR5, OAS)) { error_setg(errp, "Host SMMUv3 supports only %d-bit IPA, but the vS= MMU " "OAS implies %d-bit IPA", smmuv3_oas_bits(FIELD_EX32(info->idr[5], IDR5, OAS)), - smmuv3_oas_bits(FIELD_EX32(s->idr[5], IDR5, OAS))); + smmuv3_oas_bits(FIELD_EX32(bank->idr[5], IDR5, OAS))); return false; } /* Check ATS value opted is compatible with Host SMMUv3 */ if (FIELD_EX32(info->idr[0], IDR0, ATS) < - FIELD_EX32(s->idr[0], IDR0, ATS)) { + FIELD_EX32(bank->idr[0], IDR0, ATS)) { error_setg(errp, "Host SMMUv3 doesn't support Address Translation = Services"); return false; } =20 /* QEMU SMMUv3 supports GRAN4K/GRAN16K/GRAN64K translation granules */ if (FIELD_EX32(info->idr[5], IDR5, GRAN4K) !=3D - FIELD_EX32(s->idr[5], IDR5, GRAN4K)) { + FIELD_EX32(bank->idr[5], IDR5, GRAN4K)) { error_setg(errp, "Host SMMUv3 doesn't support 4K translation granu= le"); return false; } if (FIELD_EX32(info->idr[5], IDR5, GRAN16K) !=3D - FIELD_EX32(s->idr[5], IDR5, GRAN16K)) { + FIELD_EX32(bank->idr[5], IDR5, GRAN16K)) { error_setg(errp, "Host SMMUv3 doesn't support 16K translation gran= ule"); return false; } if (FIELD_EX32(info->idr[5], IDR5, GRAN64K) !=3D - FIELD_EX32(s->idr[5], IDR5, GRAN64K)) { + FIELD_EX32(bank->idr[5], IDR5, GRAN64K)) { error_setg(errp, "Host SMMUv3 doesn't support 64K translation gran= ule"); return false; } @@ -218,7 +220,8 @@ static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUStat= e *bs, SMMUPciBus *sbus, =20 static uint32_t smmuv3_accel_gbpa_hwpt(SMMUv3State *s, SMMUv3AccelState *a= ccel) { - return FIELD_EX32(s->gbpa, GBPA, ABORT) ? + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + return FIELD_EX32(bank->gbpa, GBPA, ABORT) ? accel->abort_hwpt_id : accel->bypass_hwpt_id; } =20 @@ -544,6 +547,8 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error *= *errp) uint32_t veventq_id; uint32_t veventq_fd; int flags; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); =20 if (!accel || !accel->viommu) { return true; @@ -560,7 +565,7 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error *= *errp) if (!iommufd_backend_alloc_veventq(accel->viommu->iommufd, accel->viommu->viommu_id, IOMMU_VEVENTQ_TYPE_ARM_SMMUV3, - 1 << s->eventq.log2size, &veventq_i= d, + 1 << bank->eventq.log2size, &vevent= q_id, &veventq_fd, errp)) { return false; } @@ -943,9 +948,10 @@ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *= bus, void *opaque, =20 static inline bool smmuv3_pasid_supported(SMMUv3State *s) { + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); return s->ssidsize > SSID_SIZE_MODE_0 || (s->ssidsize =3D=3D SSID_SIZE_MODE_AUTO && - FIELD_EX32(s->idr[1], IDR1, SSIDSIZE)); + FIELD_EX32(bank->idr[1], IDR1, SSIDSIZE)); } =20 static uint64_t smmuv3_accel_get_viommu_flags(void *opaque) @@ -997,19 +1003,20 @@ void smmuv3_accel_idr_override(SMMUv3State *s) return; } =20 + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); /* Only override RIL if user explicitly set OFF */ if (s->ril =3D=3D ON_OFF_AUTO_OFF) { - s->idr[3] =3D FIELD_DP32(s->idr[3], IDR3, RIL, 0); + bank->idr[3] =3D FIELD_DP32(bank->idr[3], IDR3, RIL, 0); } =20 /* QEMU SMMUv3 has no ATS. Advertise ATS if opt-in by property */ if (s->ats =3D=3D ON_OFF_AUTO_ON) { - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, ATS, 1); + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, ATS, 1); } =20 /* Advertise 48-bit OAS in IDR5 when requested (default is 44 bits). */ if (s->oas =3D=3D OAS_MODE_48) { - s->idr[5] =3D FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_48); + bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, OAS, SMMU_IDR5_OAS= _48); } =20 /* @@ -1017,7 +1024,7 @@ void smmuv3_accel_idr_override(SMMUv3State *s) * has enabled it. */ if (s->ssidsize > SSID_SIZE_MODE_0) { - s->idr[1] =3D FIELD_DP32(s->idr[1], IDR1, SSIDSIZE, + bank->idr[1] =3D FIELD_DP32(bank->idr[1], IDR1, SSIDSIZE, ssidsize_mode_to_value(s->ssidsize)); } } diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index 0819a4b2e8d..10154ca161d 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -41,7 +41,9 @@ typedef enum SMMUTranslationClass { =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 */ @@ -69,12 +71,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 */ @@ -119,17 +125,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 static const char *cmd_stringify[] =3D { diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index ed19536a4dc..d3baae8a32a 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -53,6 +53,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 @@ -68,15 +70,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; @@ -90,8 +92,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, @@ -103,9 +107,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) @@ -147,7 +151,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)) { @@ -275,74 +281,87 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInf= o *info) */ static void smmuv3_init_id_regs(SMMUv3State *s) { + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + /* 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); + bank->idr[0] =3D FIELD_DP32(bank->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); + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, S1P, 1); + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, S2P, 1); } else { - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, S1P, 1); - } - - 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= */ + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, S1P, 1); + } + + /* AArch64 PTW only */ + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, TTF, 2); + /* IO coherent */ + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, COHACC, 1); + /* 16-bit ASID */ + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, ASID16, 1); + /* 16-bit VMID */ + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, VMID16, 1); + /* little endian */ + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, TTENDIAN, 2); + /* No stall */ + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, STALL_MODEL, 1); /* terminated transaction will always be aborted/error returned */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, TERM_MODEL, 1); + bank->idr[0] =3D FIELD_DP32(bank->idr[0], IDR0, TERM_MODEL, 1); /* 2-level stream table supported */ - s->idr[0] =3D FIELD_DP32(s->idr[0], IDR0, STLEVEL, 1); + bank->idr[0] =3D FIELD_DP32(bank->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); + bank->idr[1] =3D FIELD_DP32(bank->idr[1], IDR1, SIDSIZE, SMMU_IDR1_SID= SIZE); + bank->idr[1] =3D FIELD_DP32(bank->idr[1], IDR1, EVENTQS, SMMU_EVENTQS); + bank->idr[1] =3D FIELD_DP32(bank->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)) { + bank->idr[3] =3D FIELD_DP32(bank->idr[3], IDR3, HAD, 1); + if (FIELD_EX32(bank->idr[0], IDR0, S2P)) { /* XNX is a stage-2-specific feature */ - s->idr[3] =3D FIELD_DP32(s->idr[3], IDR3, XNX, 1); + bank->idr[3] =3D FIELD_DP32(bank->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); + bank->idr[3] =3D FIELD_DP32(bank->idr[3], IDR3, RIL, 1); + bank->idr[3] =3D FIELD_DP32(bank->idr[3], IDR3, BBML, 2); =20 /* OAS: 44 bits */ - s->idr[5] =3D FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS_44); + bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, OAS, SMMU_IDR5_OAS_44); /* 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); + bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, GRAN4K, 1); + bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, GRAN16K, 1); + bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, GRAN64K, 1); s->aidr =3D 0x1; smmuv3_accel_idr_override(s); } =20 bool smmuv3_ats_enabled(SMMUv3State *s) { - return FIELD_EX32(s->idr[0], IDR0, ATS); + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + return FIELD_EX32(bank->idr[0], IDR0, ATS); } =20 static void smmuv3_reset(SMMUv3State *s) { - 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; - s->cr[0] =3D 0; - s->cr0ack =3D 0; - s->irq_ctrl =3D 0; - s->gerror =3D 0; - s->gerrorn =3D 0; + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + + bank->cmdq.base =3D deposit64(bank->cmdq.base, 0, 5, SMMU_CMDQS); + bank->cmdq.prod =3D 0; + bank->cmdq.cons =3D 0; + bank->cmdq.entry_size =3D sizeof(struct Cmd); + bank->eventq.base =3D deposit64(bank->eventq.base, 0, 5, SMMU_EVENTQS); + bank->eventq.prod =3D 0; + bank->eventq.cons =3D 0; + bank->eventq.entry_size =3D sizeof(struct Evt); + + bank->features =3D 0; + bank->sid_split =3D 0; + bank->cr[0] =3D 0; + bank->cr0ack =3D 0; + bank->irq_ctrl =3D 0; + bank->gerror =3D 0; + bank->gerrorn =3D 0; + bank->gbpa =3D SMMU_GBPA_RESET_VAL; + + s->aidr =3D 0x1; s->statusr =3D 0; - s->gbpa =3D SMMU_GBPA_RESET_VAL; } =20 static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, @@ -456,7 +475,8 @@ 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(s, SMMU_SEC_SID_NS)->idr[5], + IDR5, OAS); =20 if (STE_S2AA64(ste) =3D=3D 0x0) { qemu_log_mask(LOG_UNIMP, @@ -574,7 +594,9 @@ 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 field only presents on NS-IDR5 so we use hardcoded SMMU_SEC_SID= _NS */ + uint8_t oas =3D FIELD_EX32(smmuv3_bank(s, SMMU_SEC_SID_NS)->idr[5], + IDR5, OAS); int ret; =20 if (!STE_VALID(ste)) { @@ -628,7 +650,8 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg, /* Multiple context descriptors require SubstreamID support */ if ((s->ssidsize =3D=3D SSID_SIZE_MODE_0 || (s->ssidsize =3D=3D SSID_SIZE_MODE_AUTO && - !FIELD_EX32(s->idr[1], IDR1, SSIDSIZE))) && + !FIELD_EX32(smmuv3_bank(s, SMMU_SEC_SID_NS)->idr[1], + IDR1, SSIDSIZE))) && STE_S1CDMAX(ste) !=3D 0) { qemu_log_mask(LOG_UNIMP, "SMMUv3: multiple S1 context descriptors require Substream= ID support. " @@ -666,9 +689,11 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *s= te, SMMUEventInfo *event) uint32_t log2size; int strtab_size; 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 */ @@ -676,7 +701,7 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *st= e, SMMUEventInfo *event) 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; @@ -685,11 +710,11 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *= ste, SMMUEventInfo *event) * Align strtab base address to table size. For this purpose, assu= me it * is not bounded by SMMU_IDR1_SIDSIZE. */ - strtab_size =3D MAX(6, (int)log2size - s->sid_split + L1STD_SIZE); - strtab_base =3D s->strtab_base & SMMU_BASE_ADDR_MASK & + strtab_size =3D MAX(6, (int)log2size - bank->sid_split + L1STD_SIZ= E); + strtab_base =3D bank->strtab_base & SMMU_BASE_ADDR_MASK & ~MAKE_64BIT_MASK(0, strtab_size); - 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, @@ -717,7 +742,7 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *st= e, SMMUEventInfo *event) return -EINVAL; } =20 - if (span > s->sid_split + 1) { + if (span > bank->sid_split + 1) { if (!event->inval_ste_allowed) { qemu_log_mask(LOG_GUEST_ERROR, "invalid span (0x%x)\n", span); @@ -728,9 +753,8 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *st= e, SMMUEventInfo *event) =20 max_l2_ste =3D (1 << span) - 1; l2ptr =3D l1std_l2ptr(&l1std); - l2ptr &=3D ~MAKE_64BIT_MASK(0, 6 + (span - 1)); - 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, @@ -743,7 +767,7 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *st= e, SMMUEventInfo *event) } else { strtab_size =3D log2size + STE_SIZE; strtab_size =3D MIN(64, strtab_size); - 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); addr =3D strtab_base + sid * sizeof(*ste); } @@ -762,7 +786,8 @@ 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(s, SMMU_SEC_SID_NS)->idr[5], + IDR5, OAS); =20 if (!CD_VALID(cd) || !CD_AARCH64(cd)) { goto bad_cd; @@ -1084,6 +1109,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}; @@ -1101,7 +1128,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; @@ -1325,7 +1352,9 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) { 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)) { @@ -1339,7 +1368,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) */ =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), @@ -1601,29 +1630,32 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Erro= r **errp) 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, @@ -1637,11 +1669,13 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, uint64_t data, MemTxAttrs attrs) { Error *local_err =3D NULL; + SMMUSecSID reg_sec_sid =3D SMMU_SEC_SID_NS; + SMMUv3RegBank *bank =3D smmuv3_bank(s, reg_sec_sid); =20 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, &local_err); if (local_err) { @@ -1652,13 +1686,13 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, smmuv3_accel_alloc_veventq(s, &local_err); break; case A_CR1: - s->cr[1] =3D data; + bank->cr[1] =3D data; break; case A_CR2: - s->cr[2] =3D data; + bank->cr[2] =3D data; break; case A_IRQ_CTRL: - s->irq_ctrl =3D data; + bank->irq_ctrl =3D data; break; case A_GERRORN: smmuv3_write_gerrorn(s, data); @@ -1669,16 +1703,16 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, smmuv3_cmdq_consume(s, &local_err); break; 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); break; 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); break; case A_GERROR_IRQ_CFG1: - s->gerror_irq_cfg1 =3D data; + bank->gerror_irq_cfg1 =3D data; break; case A_GERROR_IRQ_CFG2: - s->gerror_irq_cfg2 =3D data; + bank->gerror_irq_cfg2 =3D data; break; case A_GBPA: /* @@ -1687,74 +1721,75 @@ 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; smmuv3_accel_attach_gbpa_hwpt(s, &local_err); } break; 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); break; 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); break; 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); - if (s->sid_split !=3D 6 && s->sid_split !=3D 8 && s->sid_split= !=3D 10) { + bank->sid_split =3D FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT); + if (bank->sid_split !=3D 6 && bank->sid_split !=3D 8 && + bank->sid_split !=3D 10) { /* Other values are reserved, behave as 6 */ qemu_log_mask(LOG_GUEST_ERROR, "Invalid STRTAB_BASE_CFG.SPLIT=3D%u, use 6 i= nstead\n", - s->sid_split); - s->sid_split =3D 6; + bank->sid_split); + bank->sid_split =3D 6; } - s->features |=3D SMMU_FEATURE_2LVL_STE; + bank->features |=3D SMMU_FEATURE_2LVL_STE; } break; 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; } break; 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); break; case A_CMDQ_PROD: - s->cmdq.prod =3D data; + bank->cmdq.prod =3D data; smmuv3_cmdq_consume(s, &local_err); break; case A_CMDQ_CONS: - s->cmdq.cons =3D data; + bank->cmdq.cons =3D data; break; 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; } break; 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); break; case A_EVENTQ_PROD: - s->eventq.prod =3D data; + bank->eventq.prod =3D data; break; case A_EVENTQ_CONS: - s->eventq.cons =3D data; + bank->eventq.cons =3D data; break; 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); break; 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); break; case A_EVENTQ_IRQ_CFG1: - s->eventq_irq_cfg1 =3D data; + bank->eventq_irq_cfg1 =3D data; break; case A_EVENTQ_IRQ_CFG2: - s->eventq_irq_cfg2 =3D data; + bank->eventq_irq_cfg2 =3D data; break; default: qemu_log_mask(LOG_UNIMP, @@ -1798,18 +1833,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; @@ -1823,12 +1861,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; @@ -1837,77 +1878,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; @@ -2089,9 +2130,10 @@ static const VMStateDescription vmstate_smmuv3_queue= =3D { static bool smmuv3_gbpa_needed(void *opaque) { SMMUv3State *s =3D opaque; + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); =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 { @@ -2100,7 +2142,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() } }; @@ -2111,27 +2153,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/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c index 273633e6293..c7c63f27bb1 100644 --- a/hw/arm/tegra241-cmdqv.c +++ b/hw/arm/tegra241-cmdqv.c @@ -974,6 +974,7 @@ static void tegra241_cmdqv_init_regs(SMMUv3State *s, Te= gra241CMDQV *cmdqv) int i; long pgsize; uint32_t val; + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); =20 cmdqv->config =3D V_CONFIG_RESET; cmdqv->param =3D FIELD_DP32(0, PARAM, CMDQV_VER, CMDQV_VER); @@ -1019,8 +1020,9 @@ static void tegra241_cmdqv_init_regs(SMMUv3State *s, = Tegra241CMDQV *cmdqv) if (pgsize =3D=3D LONG_MAX) { pgsize =3D qemu_real_host_page_size(); } - val =3D FIELD_EX32(s->idr[1], IDR1, CMDQS); - s->idr[1] =3D FIELD_DP32(s->idr[1], IDR1, CMDQS, MIN(ctz64(pgsize) - 4= , val)); + val =3D FIELD_EX32(bank->idr[1], IDR1, CMDQS); + bank->idr[1] =3D FIELD_DP32(bank->idr[1], IDR1, CMDQS, + MIN(ctz64(pgsize) - 4, val)); } =20 static void tegra241_cmdqv_reset(SMMUv3State *s) diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 7b975abc25a..6ea40f6b074 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 d39fe8850bc..45033d26a1b 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -34,19 +34,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; @@ -61,6 +55,17 @@ struct SMMUv3State { uint32_t eventq_irq_cfg2; =20 SMMUQueue eventq, 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; @@ -103,7 +108,14 @@ bool smmuv3_ats_enabled(struct SMMUv3State *s); #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]; +} =20 #endif --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638274160260.1044993497352; Thu, 13 Aug 2026 09:24:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEA-0007ui-MI; Thu, 13 Aug 2026 12:24:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYE9-0007tv-5B; Thu, 13 Aug 2026 12:24:21 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYE7-0000WN-5c; Thu, 13 Aug 2026 12:24:20 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwDHyXWw731q_hpvAw--.20295S2; Fri, 14 Aug 2026 00:24:16 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwjnOq731q3SwjAA--.59176S5; Fri, 14 Aug 2026 00:24:14 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 03/28] hw/arm/smmuv3: Thread SEC_SID through helper APIs Date: Fri, 14 Aug 2026 00:24:08 +0800 Message-Id: <20260813162410.2805113-3-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwjnOq731q3SwjAA--.59176S5 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HjgACsb Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3XrWfurW3Gw1UKF4xZr17Awb_yoWxXw47pw 4DJFn5KryUtF9YgFW7Jw48C3W3Xw4fKFn8Krn8Ga93C3WUAr1UXr1kG345KasF9ry8Ca1a v3ySgF48uw47ArJanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638279264158500 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 Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Link: https://lore.kernel.org/qemu-devel/3097d58e-3793-4434-8beb-2e4f4c52f7= 72@redhat.com/ Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3-accel.c | 5 +++-- hw/arm/smmuv3-internal.h | 21 +++++++++------------ hw/arm/smmuv3.c | 15 ++++++++------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 3ff3da66acd..fa079c8acea 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -294,6 +294,7 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevic= e *sdev, int sid, SMMUS1Hwpt *s1_hwpt =3D NULL; const char *type; STE ste; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; =20 if (!accel || !accel->viommu) { return true; @@ -323,7 +324,7 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevic= e *sdev, int sid, * attach/alloc fails, since the Guest=E2=80=93Host SID mapping stays * valid as long as the device is behind the accelerated SMMUv3. */ - if (!smmu_enabled(s)) { + if (!smmu_enabled(s, sec_sid)) { hwpt_id =3D smmuv3_accel_gbpa_hwpt(s, accel); } else { config =3D STE_CONFIG(&ste); @@ -558,7 +559,7 @@ bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error *= *errp) return true; } =20 - if (!smmuv3_eventq_enabled(s)) { + if (!smmuv3_eventq_enabled(s, sec_sid)) { return true; } =20 diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index 10154ca161d..a88743ba9cd 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -39,9 +39,8 @@ typedef enum SMMUTranslationClass { SMMU_CLASS_IN, } SMMUTranslationClass; =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); } @@ -69,16 +68,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); } @@ -123,23 +122,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 d3baae8a32a..51e970d710a 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -60,7 +60,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"); @@ -80,7 +80,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; } } @@ -156,7 +156,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 @@ -191,8 +191,9 @@ void smmuv3_propagate_event(SMMUv3State *s, Evt *evt) void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info) { Evt evt =3D {}; + SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; =20 - if (!smmuv3_eventq_enabled(s)) { + if (!smmuv3_eventq_enabled(s, sec_sid)) { return; } =20 @@ -1127,7 +1128,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 { @@ -1357,7 +1358,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) SMMUQueue *q =3D &bank->cmdq; SMMUCommandType type =3D 0; =20 - if (!smmuv3_cmdq_enabled(s)) { + if (!smmuv3_cmdq_enabled(s, sec_sid)) { return 0; } /* @@ -1617,7 +1618,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) =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 Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178663854211628.136769297922342; Thu, 13 Aug 2026 09:29:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYED-0007yd-34; Thu, 13 Aug 2026 12:24:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEA-0007um-Qb; Thu, 13 Aug 2026 12:24:22 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYE8-0000Ww-RF; Thu, 13 Aug 2026 12:24:22 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwCXn3uy731qExtvAw--.34194S2; Fri, 14 Aug 2026 00:24:18 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwjnOq731q3SwjAA--.59176S6; Fri, 14 Aug 2026 00:24:15 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 04/28] hw/arm/smmuv3: Track SEC_SID in configs and events Date: Fri, 14 Aug 2026 00:24:09 +0800 Message-Id: <20260813162410.2805113-4-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwjnOq731q3SwjAA--.59176S6 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HkgAAsF Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3GF45JFW3AF4rtryUtryrJFb_yoW3GrW5pr 1DGrn8Kr1DtF1fZF13Xa18A3W3Xw18KrnxtryqgFyrAw4DAry7XF4DGw1Ykr909rWjv3y2 vayIgF45ury7A3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638543199158500 Content-Type: text/plain; charset="utf-8" Pass the SEC_SID explicitly to smmuv3_decode_config() so configuration decoding can be 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 Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3-accel.c | 2 +- hw/arm/smmuv3-internal.h | 3 ++- hw/arm/smmuv3.c | 26 +++++++++++++++----------- hw/arm/trace-events | 2 +- include/hw/arm/smmuv3.h | 1 + 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index fa079c8acea..2ce94786829 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -509,7 +509,7 @@ static void smmuv3_accel_event_read(void *opaque) if (ret > 0) { return; /* EAGAIN/EINTR */ } - smmuv3_propagate_event(s, (Evt *)&buf.vevent); + smmuv3_propagate_event(s, (Evt *)&buf.vevent, SMMU_SEC_SID_NS); } =20 static void smmuv3_accel_free_veventq(SMMUv3AccelState *accel) diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index a88743ba9cd..202cd533636 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -274,6 +274,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; @@ -365,7 +366,7 @@ typedef struct SMMUEventInfo { #define EVT_GET_SID(x) ((x)->word[1]) =20 void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event); -void smmuv3_propagate_event(SMMUv3State *s, Evt *evt); +void smmuv3_propagate_event(SMMUv3State *s, Evt *evt, SMMUSecSID sec_sid); int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *e= vent); =20 #define STE_SIZE 6 diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 51e970d710a..649050b9347 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -149,9 +149,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; @@ -175,14 +175,14 @@ static MemTxResult smmuv3_write_eventq(SMMUv3State *s= , Evt *evt) return MEMTX_OK; } =20 -void smmuv3_propagate_event(SMMUv3State *s, Evt *evt) +void smmuv3_propagate_event(SMMUv3State *s, Evt *evt, SMMUSecSID sec_sid) { MemTxResult r; =20 - trace_smmuv3_propagate_event(smmu_event_string(EVT_GET_TYPE(evt)), + trace_smmuv3_propagate_event(sec_sid, smmu_event_string(EVT_GET_TYPE(e= vt)), EVT_GET_SID(evt)); QEMU_LOCK_GUARD(&s->mutex); - r =3D smmuv3_write_eventq(s, evt); + 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); } @@ -191,7 +191,7 @@ void smmuv3_propagate_event(SMMUv3State *s, Evt *evt) void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info) { Evt evt =3D {}; - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + SMMUSecSID sec_sid =3D info->sec_sid; =20 if (!smmuv3_eventq_enabled(s, sec_sid)) { return; @@ -271,7 +271,7 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo = *info) g_assert_not_reached(); } =20 - smmuv3_propagate_event(s, &evt); + smmuv3_propagate_event(s, &evt, sec_sid); info->recorded =3D true; } =20 @@ -886,12 +886,13 @@ bad_cd: * @cfg: output translation configuration which is populated through * the different configuration decoding steps * @event: must be zero'ed by the caller + * @sec_sid: StreamID Security state * * return < 0 in case of config decoding error (@event is filled * accordingly). Return 0 otherwise. */ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg, - SMMUEventInfo *event) + SMMUEventInfo *event, SMMUSecSID sec_sid) { SMMUDevice *sdev =3D container_of(mr, SMMUDevice, iommu); uint32_t sid =3D smmu_get_sid(sdev); @@ -958,7 +959,7 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev= , SMMUEventInfo *event) (sdev->cfg_cache_hits + sdev->cfg_cache_misses= )); cfg =3D g_new0(SMMUTransCfg, 1); =20 - if (!smmuv3_decode_config(&sdev->iommu, cfg, event)) { + if (!smmuv3_decode_config(&sdev->iommu, cfg, event, SMMU_SEC_SID_N= S)) { g_hash_table_insert(bc->configs, sdev, cfg); } else { g_free(cfg); @@ -1114,7 +1115,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 { @@ -1216,7 +1218,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 1b16f710fed..a166b79c8ef 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -41,7 +41,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_propagate_event(const char *type, uint32_t sid) "%s sid=3D0x%x" +smmuv3_propagate_event(int sec_sid, const char *type, uint32_t sid) "sec_s= id=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/smmuv3.h b/include/hw/arm/smmuv3.h index 45033d26a1b..8cd2edc3412 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -115,6 +115,7 @@ OBJECT_DECLARE_TYPE(SMMUv3State, SMMUv3Class, ARM_SMMUV= 3) =20 static inline SMMUv3RegBank *smmuv3_bank(SMMUv3State *s, SMMUSecSID sec_si= d) { + g_assert(sec_sid < SMMU_SEC_SID_NUM); return &s->bank[sec_sid]; } =20 --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638315379510.88466264515273; Thu, 13 Aug 2026 09:25:15 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYED-0007yv-T4; Thu, 13 Aug 2026 12:24:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEB-0007xH-EB; Thu, 13 Aug 2026 12:24:23 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYE9-0000XG-PS; Thu, 13 Aug 2026 12:24:23 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwAHDhqx731qEhtvAw--.34541S2; Fri, 14 Aug 2026 00:24:17 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwjnOq731q3SwjAA--.59176S7; Fri, 14 Aug 2026 00:24:16 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 05/28] hw/arm/smmu-common: Add security-aware address space selector Date: Fri, 14 Aug 2026 00:24:10 +0800 Message-Id: <20260813162410.2805113-5-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwjnOq731q3SwjAA--.59176S7 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HkgABsE Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7try7XFW3Ary5WF1DWw4UArb_yoW8CFy8pa n7Cr93Ar92kF1I9rZ3Zr4a9FyUuws3GF1UGry2gF95Cw17tr1fAr1UKw1jkrZrCr1Fqr47 uFWxZrs5WF1UtrJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638316214158500 Content-Type: text/plain; charset="utf-8" Introduce SMMU_SEC_SID_S to represent SEC_SID =3D=3D 1, meaning Secure. And then provide smmu_get_address_space, a SMMU instance-based address space selector. The helper returns the per-device memory or secure-memory AddressSpace selected by SEC_SID. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 15 +++++++++++++++ include/hw/arm/smmu-common.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 8e40ba603d3..54a6a9f4d62 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -30,6 +30,21 @@ #include "hw/arm/smmu-common.h" #include "smmu-internal.h" =20 +AddressSpace *smmu_get_address_space(SMMUState *s, SMMUSecSID sec_sid) +{ + switch (sec_sid) { + case SMMU_SEC_SID_NS: + return &s->memory_as; + case SMMU_SEC_SID_S: + g_assert(s->secure_memory); + g_assert(s->secure_memory_as.root); + return &s->secure_memory_as; + case SMMU_SEC_SID_NUM: + g_assert_not_reached(); + } + g_assert_not_reached(); +} + /* IOTLB Management */ =20 static guint smmu_iotlb_key_hash(gconstpointer v) diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 6ea40f6b074..9d6e2d3038f 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -43,6 +43,7 @@ /* StreamID Security state */ typedef enum SMMUSecSID { SMMU_SEC_SID_NS =3D 0, + SMMU_SEC_SID_S, SMMU_SEC_SID_NUM, } SMMUSecSID; =20 @@ -188,6 +189,8 @@ struct SMMUBaseClass { #define TYPE_ARM_SMMU "arm-smmu" OBJECT_DECLARE_TYPE(SMMUState, SMMUBaseClass, ARM_SMMU) =20 +AddressSpace *smmu_get_address_space(SMMUState *s, SMMUSecSID sec_sid); + /* Return the SMMUPciBus handle associated to a PCI bus number */ SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num); =20 --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638580790855.0174092483232; Thu, 13 Aug 2026 09:29:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEs-0000P5-6r; Thu, 13 Aug 2026 12:25:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEk-000076-50; Thu, 13 Aug 2026 12:24:59 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEf-0000g3-8F; Thu, 13 Aug 2026 12:24:55 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwDHzLTQ731qVVDmAA--.5027S2; Fri, 14 Aug 2026 00:24:48 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwF3PO731q3ywjAA--.59573S3; Fri, 14 Aug 2026 00:24:47 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 06/28] hw/arm/smmuv3: Plumb transaction attributes into config helpers Date: Fri, 14 Aug 2026 00:24:42 +0800 Message-Id: <20260813162446.2806393-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwF3PO731q3ywjAA--.59573S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HlQAAsC Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWfGr4kArWUXry8CFWkCr47twb_yoWkur43pr 47GFn0kw4rtFyfZF93JF4j93W5Z3yvgFn8GryDKF9YyF1jyryxZr1DK343CryDury8JFsr ZayIgF45Zr17A3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638581670158500 Content-Type: text/plain; charset="utf-8" Introduce helpers that derive MemTxAttrs and select an AddressSpace from SEC_SID, then pass SEC_SID through the Stream Table and Context Descriptor fetch paths. This makes reads of SMMU configuration structures use the corresponding Non-secure or Secure memory context. To support these helpers, include hw/arm/arm-security.h from smmu-common.h, making the Arm security-space definitions available to the common SMMU code. The accelerated path remains Non-secure-only and therefore passes SMMU_SEC_SID_NS explicitly. For now, the configuration cache lookup key remains based solely on the SMMUDevice pointer. It is extended with SEC_SID in a later commit. Other SEC_SID-sensitive memory accesses that still use the Non-secure address space are converted in follow-up commits. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 30 +++++++++++++++++++++---- hw/arm/smmuv3-accel.c | 2 +- hw/arm/smmuv3-internal.h | 3 ++- hw/arm/smmuv3.c | 43 ++++++++++++++++++++++-------------- include/hw/arm/smmu-common.h | 10 +++++++++ 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 54a6a9f4d62..89e1e2826d4 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -30,6 +30,27 @@ #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: + return ARMSS_NonSecure; + case SMMU_SEC_SID_NUM: + g_assert_not_reached(); + } + g_assert_not_reached(); +} + +MemTxAttrs smmu_get_txattrs(SMMUSecSID sec_sid) +{ + return (MemTxAttrs) { + .secure =3D smmu_sec_sid_is_secure(sec_sid) ? 1 : 0, + .space =3D smmu_get_security_space(sec_sid), + }; +} + AddressSpace *smmu_get_address_space(SMMUState *s, SMMUSecSID sec_sid) { switch (sec_sid) { @@ -588,6 +609,7 @@ error: /** * smmu_ptw_64_s2 - VMSAv8-64 Walk of the page tables for a given ipa * for stage-2. + * @bs: smmu state which includes TLB instance * @cfg: translation config * @ipa: ipa to translate * @perm: access type @@ -599,7 +621,7 @@ error: * Upon success, @tlbe is filled with translated_addr and entry * permission rights. */ -static int smmu_ptw_64_s2(SMMUTransCfg *cfg, +static int smmu_ptw_64_s2(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t ipa, IOMMUAccessFlags perm, SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info) { @@ -636,7 +658,6 @@ static int smmu_ptw_64_s2(SMMUTransCfg *cfg, uint64_t pte, gpa; dma_addr_t pte_addr =3D baseaddr + offset * sizeof(pte); uint8_t s2ap; - if (get_pte(baseaddr, offset, &pte, info)) { goto error; } @@ -690,6 +711,7 @@ static int smmu_ptw_64_s2(SMMUTransCfg *cfg, goto error_ipa; } =20 + tlbe->entry.target_as =3D &bs->memory_as; tlbe->entry.translated_addr =3D gpa; tlbe->entry.iova =3D ipa & ~mask; tlbe->entry.addr_mask =3D mask; @@ -765,7 +787,7 @@ int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr= _t iova, return -EINVAL; } =20 - return smmu_ptw_64_s2(cfg, iova, perm, tlbe, info); + return smmu_ptw_64_s2(bs, cfg, iova, perm, tlbe, info); } =20 /* SMMU_NESTED. */ @@ -775,7 +797,7 @@ int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr= _t iova, } =20 ipa =3D CACHED_ENTRY_TO_ADDR(tlbe, iova); - ret =3D smmu_ptw_64_s2(cfg, ipa, perm, &tlbe_s2, info); + ret =3D smmu_ptw_64_s2(bs, cfg, ipa, perm, &tlbe_s2, info); if (ret) { return ret; } diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 2ce94786829..9d207acc8e3 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -310,7 +310,7 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevic= e *sdev, int sid, return false; } =20 - if (smmu_find_ste(sdev->smmu, sid, &ste, &event)) { + if (smmu_find_ste(sdev->smmu, sid, &ste, &event, sec_sid)) { /* No STE found, nothing to install */ return true; } diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h index 202cd533636..1f2f426da01 100644 --- a/hw/arm/smmuv3-internal.h +++ b/hw/arm/smmuv3-internal.h @@ -367,7 +367,8 @@ typedef struct SMMUEventInfo { =20 void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event); void smmuv3_propagate_event(SMMUv3State *s, Evt *evt, SMMUSecSID sec_sid); -int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *e= vent); +int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *e= vent, + SMMUSecSID sec_sid); =20 #define STE_SIZE 6 #define L1STD_SIZE 3 diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 649050b9347..b5dc67dcb01 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -366,14 +366,15 @@ static void smmuv3_reset(SMMUv3State *s) } =20 static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, - SMMUEventInfo *event) + SMMUEventInfo *event, SMMUSecSID sec_sid) { + AddressSpace *as =3D smmu_get_address_space(ARM_SMMU(s), sec_sid); + MemTxAttrs txattrs =3D smmu_get_txattrs(sec_sid); 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(as, addr, buf, sizeof(*buf), txattrs); if (ret !=3D MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "Cannot fetch pte at address=3D0x%"PRIx64"\n", addr); @@ -396,12 +397,15 @@ static SMMUTranslationStatus smmuv3_do_translate(SMMU= v3State *s, hwaddr addr, SMMUTranslationClass clas= s); /* @ssid > 0 not supported yet */ static int smmu_get_cd(SMMUv3State *s, STE *ste, SMMUTransCfg *cfg, - uint32_t ssid, CD *buf, SMMUEventInfo *event) + uint32_t ssid, CD *buf, SMMUEventInfo *event, + SMMUSecSID sec_sid) { dma_addr_t addr =3D STE_CTXPTR(ste); int ret, i; SMMUTranslationStatus status; SMMUTLBEntry *entry; + AddressSpace *as; + MemTxAttrs txattrs; =20 trace_smmuv3_get_cd(addr); =20 @@ -417,9 +421,10 @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, SMMUT= ransCfg *cfg, addr =3D CACHED_ENTRY_TO_ADDR(entry, addr); } =20 + as =3D smmu_get_address_space(ARM_SMMU(s), sec_sid); + txattrs =3D smmu_get_txattrs(sec_sid); /* 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(as, addr, buf, sizeof(*buf), txattrs); if (ret !=3D MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "Cannot fetch pte at address=3D0x%"PRIx64"\n", addr); @@ -680,18 +685,21 @@ bad_ste: * @sid: stream ID * @ste: returned stream table entry * @event: handle to an event info + * @sec_sid: StreamID Security state * * Supports linear and 2-level stream table * Return 0 on success, -EINVAL otherwise */ -int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *e= vent) +int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, SMMUEventInfo *e= vent, + SMMUSecSID sec_sid) { dma_addr_t addr, strtab_base; uint32_t log2size; int strtab_size; int ret; - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + AddressSpace *as =3D smmu_get_address_space(ARM_SMMU(s), sec_sid); + MemTxAttrs txattrs =3D smmu_get_txattrs(sec_sid); =20 trace_smmuv3_find_ste(sid, bank->features, bank->sid_split); log2size =3D FIELD_EX32(bank->strtab_base_cfg, STRTAB_BASE_CFG, LOG2SI= ZE); @@ -718,8 +726,7 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *st= e, SMMUEventInfo *event) 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(as, l1ptr, &l1std, sizeof(l1std), txattrs); if (ret !=3D MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "Could not read L1PTR at 0X%"PRIx64"\n", l1ptr); @@ -773,7 +780,7 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *st= e, SMMUEventInfo *event) addr =3D strtab_base + sid * sizeof(*ste); } =20 - if (smmu_get_ste(s, addr, ste, event)) { + if (smmu_get_ste(s, addr, ste, event, sec_sid)) { return -EINVAL; } =20 @@ -904,7 +911,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, sec_sid); if (ret) { return ret; } @@ -918,7 +925,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, = SMMUTransCfg *cfg, return 0; } =20 - ret =3D smmu_get_cd(s, &ste, cfg, 0 /* ssid */, &cd, event); + ret =3D smmu_get_cd(s, &ste, cfg, 0 /* ssid */, &cd, event, sec_sid); if (ret) { return ret; } @@ -933,12 +940,14 @@ 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. */ -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; @@ -959,7 +968,7 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev= , SMMUEventInfo *event) (sdev->cfg_cache_hits + sdev->cfg_cache_misses= )); cfg =3D g_new0(SMMUTransCfg, 1); =20 - if (!smmuv3_decode_config(&sdev->iommu, cfg, event, SMMU_SEC_SID_N= S)) { + if (!smmuv3_decode_config(&sdev->iommu, cfg, event, sec_sid)) { g_hash_table_insert(bc->configs, sdev, cfg); } else { g_free(cfg); @@ -1139,7 +1148,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; @@ -1221,7 +1230,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 9d6e2d3038f..a31ffcf6e71 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -22,6 +22,7 @@ #include "hw/core/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); + /* * Page table walk error types */ @@ -200,6 +204,12 @@ SMMUPciBus *smmu_get_sbus(SMMUState *s, PCIBus *bus); /* Initialize SMMUDevice handle associated to a SMMUPciBus */ void smmu_init_sdev(SMMUState *s, SMMUDevice *sdev, PCIBus *bus, int devfn= ); =20 + +static inline bool smmu_sec_sid_is_secure(SMMUSecSID sec_sid) +{ + return sec_sid =3D=3D SMMU_SEC_SID_S; +} + /* Return the stream ID of an SMMU device */ static inline uint16_t smmu_get_sid(SMMUDevice *sdev) { --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638340177601.729504894867; Thu, 13 Aug 2026 09:25:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEr-0000Lu-0F; Thu, 13 Aug 2026 12:25:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEk-00006U-1K; Thu, 13 Aug 2026 12:24:58 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEf-0000gB-8E; Thu, 13 Aug 2026 12:24:55 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwCXK1DR731qGh5vAw--.15399S2; Fri, 14 Aug 2026 00:24:49 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwF3PO731q3ywjAA--.59573S4; Fri, 14 Aug 2026 00:24:48 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 07/28] hw/arm/smmuv3: Reject secure STEs with stage-2 enabled Date: Fri, 14 Aug 2026 00:24:43 +0800 Message-Id: <20260813162446.2806393-2-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwF3PO731q3ywjAA--.59573S4 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HlwAAsA Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7tr4UtFWxtr4kWFWfGw4xCrg_yoW8WrWxpr 4DGws5Kr4ftas3ZrZxZw48Za9xWa97Jr97GFy29as3AF4qvr1UJrnFk3W5Kr9xuryftFyU XayIgFn8ZF1qyFDanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638342098158500 Content-Type: text/plain; charset="utf-8" Pass sec_sid into decode_ste() and treat a secure STE that enables stage-2 translation as an illegal STE. The current model does not implement Secure stage-2 translation, so reject Secure STE configurations that enable stage 2 and report BAD_STE. This restriction can be relaxed when SEL2 and Secure stage-2 support are implemented. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index b5dc67dcb01..3ff2f498a3b 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -597,7 +597,7 @@ static void decode_ste_config(SMMUTransCfg *cfg, uint32= _t config) =20 /* Returns < 0 in case of invalid STE, 0 otherwise */ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg, - STE *ste, SMMUEventInfo *event) + STE *ste, SMMUEventInfo *event, SMMUSecSID sec_sid) { uint32_t config; /* OAS field only presents on NS-IDR5 so we use hardcoded SMMU_SEC_SID= _NS */ @@ -651,6 +651,14 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cf= g, if (ret) { goto bad_ste; } + + /* + * It is ILLEGAL to set STE.Config =3D=3D 0b11x according to (IHI = 0070G.b) + * 5.2 STE, Stream Table Entry, Page 218. + */ + if (sec_sid =3D=3D SMMU_SEC_SID_S) { + goto bad_ste; + } } =20 /* Multiple context descriptors require SubstreamID support */ @@ -916,7 +924,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, = SMMUTransCfg *cfg, return ret; } =20 - ret =3D decode_ste(s, cfg, &ste, event); + ret =3D decode_ste(s, cfg, &ste, event, sec_sid); if (ret) { return ret; } --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638314525826.7099072774138; Thu, 13 Aug 2026 09:25:14 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEp-0000Fn-Uu; Thu, 13 Aug 2026 12:25:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEk-00007A-4u; Thu, 13 Aug 2026 12:24:59 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEg-0000gv-8B; Thu, 13 Aug 2026 12:24:57 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwCXK1DT731qQh5vAw--.15404S2; Fri, 14 Aug 2026 00:24:51 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwF3PO731q3ywjAA--.59573S5; Fri, 14 Aug 2026 00:24:48 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 08/28] hw/arm/smmu-common: Key configuration cache on SMMUDevice and SEC_SID Date: Fri, 14 Aug 2026 00:24:44 +0800 Message-Id: <20260813162446.2806393-3-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwF3PO731q3ywjAA--.59573S5 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HmQAAsO Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxtFWUZr1UCF1xJFW3urWUtwb_yoWxZw4xpr W8JF98Gr4UGF1fCFs3XFWxu3Z8Wwn2gF1fGryagr9YyFyqyry8AF4DK3yYk3s7CrWkJF47 ZayxWFyUCr1xAaDanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638316287158500 Content-Type: text/plain; charset="utf-8" Adapt the configuration cache to distinguish entries decoded through different SEC_SID-selected programming interfaces by introducing a composite SMMUConfigKey. The key combines SMMUDevice with SEC_SID, preventing Secure and Non-secure configuration entries from aliasing in the cache and leaving the key extensible for a future Realm SEC_SID namespace. The cache lookup, insertion, and invalidation mechanisms are updated to use this new keying infrastructure. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Link: https://lore.kernel.org/qemu-devel/a9a840a6-c65f-4352-9a49-ddd1b5483f= 43@redhat.com/ Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 45 ++++++++++++++++++++++++++++++++++-- hw/arm/smmuv3.c | 12 ++++++---- include/hw/arm/smmu-common.h | 7 ++++++ 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 89e1e2826d4..63c36329a98 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) { @@ -265,7 +285,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 @@ -283,6 +304,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) { @@ -979,7 +1018,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 3ff2f498a3b..a01175cc672 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -952,7 +952,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, = SMMUTransCfg *cfg, * * 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) @@ -960,8 +960,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), @@ -977,7 +978,9 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev= , SMMUEventInfo *event, cfg =3D g_new0(SMMUTransCfg, 1); =20 if (!smmuv3_decode_config(&sdev->iommu, cfg, event, sec_sid)) { - 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; @@ -991,8 +994,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 a31ffcf6e71..bd83648b14c 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -153,6 +153,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; @@ -247,6 +252,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); @@ -256,6 +262,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 Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638324862785.2506943033402; Thu, 13 Aug 2026 09:25:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEp-0000Fo-W0; Thu, 13 Aug 2026 12:25:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEm-0000AV-7w; Thu, 13 Aug 2026 12:25:00 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEi-0000hd-58; Thu, 13 Aug 2026 12:24:58 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwA3PhrT731qTx5vAw--.34715S2; Fri, 14 Aug 2026 00:24:51 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwF3PO731q3ywjAA--.59573S6; Fri, 14 Aug 2026 00:24:49 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 09/28] hw/arm/smmu: Add PTE NS/NSTable helpers Date: Fri, 14 Aug 2026 00:24:45 +0800 Message-Id: <20260813162446.2806393-4-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwF3PO731q3ywjAA--.59573S6 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HmQABsP Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7uFW7tFW5Wr4fAr4UXw1DZFb_yoW8JFyrp3 4DKwn3Kry5Ja1xKa1xGw4SkFn5Xws5JF1UGr9F9r98ua1Yqa4rXr12yr4rKa4DKFyrJwnx ur4qv348WrWjqr7anT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638328482158500 Content-Type: text/plain; charset="utf-8" Add helper macros for NS and NSTable bits and group PTE attribute accessors for clarity. No functional change beyond the new helpers. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Reviewed-by: Eric Auger Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmu-internal.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h index d143d296f34..004abd58bca 100644 --- a/hw/arm/smmu-internal.h +++ b/hw/arm/smmu-internal.h @@ -58,16 +58,27 @@ ((level =3D=3D 3) && = \ ((pte & ARM_LPAE_PTE_TYPE_MASK) =3D=3D ARM_LPAE_L3_PTE_TYPE_PAGE)) =20 +/* Stage 1 attribute fields in VMSAv8-64 Block and Page descriptors */ +/* Non-secure bit */ +#define PTE_NS(pte) \ + (extract64(pte, 5, 1)) + /* access permissions */ =20 #define PTE_AP(pte) \ (extract64(pte, 6, 2)) =20 +/* Stage 1 VMSAv8-64 Table descriptor fields */ #define PTE_APTABLE(pte) \ (extract64(pte, 61, 2)) =20 +#define PTE_NSTABLE(pte) \ + (extract64(pte, 63, 1)) + +/* Access flag: defined for both Block/Page and Table descriptors. */ #define PTE_AF(pte) \ (extract64(pte, 10, 1)) + /* * TODO: At the moment all transactions are considered as privileged (EL1) * as IOMMU translation callback does not pass user/priv attributes. --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638359417207.41589652767573; Thu, 13 Aug 2026 09:25:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEs-0000Ou-5f; Thu, 13 Aug 2026 12:25:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYEk-00006z-4k; Thu, 13 Aug 2026 12:24:58 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYEg-0000h5-9j; Thu, 13 Aug 2026 12:24:56 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwDX3_fT731qaFDmAA--.4893S2; Fri, 14 Aug 2026 00:24:51 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwF3PO731q3ywjAA--.59573S7; Fri, 14 Aug 2026 00:24:50 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 10/28] hw/arm/smmuv3: Store CD NSCFG in TT info Date: Fri, 14 Aug 2026 00:24:46 +0800 Message-Id: <20260813162446.2806393-5-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwF3PO731q3ywjAA--.59573S7 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HmQACsM Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7ZF4rWF13urWDAFWkJr4kCrg_yoW8Gr4rpa s7Cr98KrWxCF129r9Fvr47u3ZrWw4kGr4UKrW7Wr9av398t39xAr1Ut3Z0kr97urW5Kr47 uF1Ivr95JF1UtrJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638360052158500 Content-Type: text/plain; charset="utf-8" With NSCFG definitions in place, record the per-table NSCFG bits in SMMUTransTableInfo during CD decode for later use. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 1 + include/hw/arm/smmu-common.h | 1 + 2 files changed, 2 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index a01175cc672..6b34f76f11b 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -881,6 +881,7 @@ static int decode_cd(SMMUv3State *s, SMMUTransCfg *cfg, tt->ttb =3D CACHED_ENTRY_TO_ADDR(entry, tt->ttb); } =20 + tt->nscfg =3D CD_NSCFG(cd, i); tt->had =3D CD_HAD(cd, i); trace_smmuv3_decode_cd_tt(i, tt->tsz, tt->ttb, tt->granule_sz, tt-= >had); } diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index bd83648b14c..1aa4e3208da 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -83,6 +83,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 T= T */ } SMMUTransTableInfo; =20 typedef struct SMMUTLBEntry { --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638453938565.0365914979557; Thu, 13 Aug 2026 09:27:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYF8-00013O-1l; Thu, 13 Aug 2026 12:25:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYF6-0000zY-Iv; Thu, 13 Aug 2026 12:25:20 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYF3-0000zR-CX; Thu, 13 Aug 2026 12:25:20 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwC3qaHq731qtVDmAA--.5006S2; Fri, 14 Aug 2026 00:25:14 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBnPo731q5SwjAA--.54277S3; Fri, 14 Aug 2026 00:25:12 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 11/28] hw/arm/smmu-common: Implement secure state handling in ptw Date: Fri, 14 Aug 2026 00:25:08 +0800 Message-Id: <20260813162512.2807281-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBnPo731q5SwjAA--.54277S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HnQAAsK Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoW3trWxCF4kJF1kuw45Cr17Wrg_yoW8Jw1xAo WfCr4Yg348uw13u3Wjkr18Ja97uFWkWw4Fqr4Yyr4a9a17A345GFyUtws8Zanaq348JF4f JFykJa1rXF1xAFn5n29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXasCq-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=lists1p.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, 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: 1786638456706158500 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 effective security state to fetch page-table entries from either the Secure or Non-secure address space, with explicit transaction attributes matching that 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. - The final TLB entry is tagged with the correct output address space, ensuring proper memory isolation. Note: We do not yet support secure stage 2 translations. This patch only implements Secure stage 1 page-table walks. Baseline propagation of the incoming NS attribute for stage 1 bypass is handled separately in this series with ATTR_PERMS_OVR =3D=3D 0. Full ATTR_PERMS_OVR support is left for a separate series. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 73 +++++++++++++++++++++++++++++------- hw/arm/smmuv3.c | 19 ++++++---- include/hw/arm/smmu-common.h | 7 ++-- 3 files changed, 74 insertions(+), 25 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 63c36329a98..317cfafded2 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -408,13 +408,13 @@ 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, AddressSpace *as, MemTxAttrs at= trs) { int ret; dma_addr_t addr =3D baseaddr + index * sizeof(*pte); =20 /* 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; @@ -488,7 +488,8 @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_ad= dr_t iova) static inline int translate_table_addr_ipa(SMMUState *bs, dma_addr_t *table_addr, SMMUTransCfg *cfg, - SMMUPTWEventInfo *info) + SMMUPTWEventInfo *info, + SMMUSecSID sec_sid) { dma_addr_t addr =3D *table_addr; SMMUTLBEntry *cached_entry; @@ -501,7 +502,7 @@ static inline int translate_table_addr_ipa(SMMUState *b= s, asid =3D cfg->asid; cfg->stage =3D SMMU_STAGE_2; cfg->asid =3D -1; - cached_entry =3D smmu_translate(bs, cfg, addr, IOMMU_RO, info); + cached_entry =3D smmu_translate(bs, cfg, addr, IOMMU_RO, info, sec_sid= ); cfg->asid =3D asid; cfg->stage =3D SMMU_NESTED; =20 @@ -524,6 +525,7 @@ static inline int translate_table_addr_ipa(SMMUState *b= s, * @perm: access type * @tlbe: SMMUTLBEntry (out) * @info: handle to an error info + * @sec_sid: StreamID Security state * * Return 0 on success, < 0 on error. In case of error, @info is filled * and tlbe->perm is set to IOMMU_NONE. @@ -532,12 +534,16 @@ static inline int translate_table_addr_ipa(SMMUState = *bs, */ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm, - SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info) + SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info, + SMMUSecSID sec_sid) { dma_addr_t baseaddr, indexmask; SMMUStage stage =3D cfg->stage; SMMUTransTableInfo *tt =3D select_tt(cfg, iova); uint8_t level, granule_sz, inputsize, stride; + int nscfg, current_ns, new_nstable; + bool sid_is_ns =3D sec_sid =3D=3D SMMU_SEC_SID_NS; + SMMUSecSID table_sec_sid; =20 if (!tt || tt->disabled) { info->type =3D SMMU_PTW_ERR_TRANSLATION; @@ -552,6 +558,7 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg *= cfg, =20 baseaddr =3D extract64(tt->ttb, 0, cfg->oas); baseaddr &=3D ~indexmask; + nscfg =3D tt->nscfg; =20 while (level < VMSA_LEVELS) { uint64_t subpage_size =3D 1ULL << level_shift(level, granule_sz); @@ -560,8 +567,19 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg = *cfg, uint64_t pte, gpa; dma_addr_t pte_addr =3D baseaddr + offset * sizeof(pte); uint8_t ap; + AddressSpace *pte_as; + MemTxAttrs pte_attrs; + SMMUSecSID cur_sec_sid; =20 - if (get_pte(baseaddr, offset, &pte, info)) { + /* + * Start in NS for Non-secure streams or CD.NSCFGx =3D=3D 1. + * Once walk is in NS, NSTable is ignored on subsequent levels. + */ + current_ns =3D sid_is_ns || nscfg; + table_sec_sid =3D current_ns ? SMMU_SEC_SID_NS : sec_sid; + pte_as =3D smmu_get_address_space(bs, table_sec_sid); + pte_attrs =3D smmu_get_txattrs(table_sec_sid); + if (get_pte(baseaddr, offset, &pte, info, pte_as, pte_attrs)) { goto error; } trace_smmu_ptw_level(stage, level, iova, subpage_size, @@ -582,10 +600,25 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg= *cfg, } baseaddr =3D get_table_pte_address(pte, granule_sz); if (cfg->stage =3D=3D SMMU_NESTED) { - if (translate_table_addr_ipa(bs, &baseaddr, cfg, info)) { + if (translate_table_addr_ipa(bs, &baseaddr, cfg, + info, table_sec_sid)) { goto error; } } + + /* + * NSTable can switch the walk to NS only while the current wa= lk + * level is Secure. Once switched to NS, NSTable is ignored ac= cording + * to hierarchical control of Secure/Non-secure accesses: + * (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 (!current_ns) { + new_nstable =3D PTE_NSTABLE(pte); + nscfg =3D new_nstable ? 1 : 0; + } else { + nscfg =3D 1; + } level++; continue; } else if (is_page_pte(pte, level)) { @@ -628,6 +661,12 @@ static int smmu_ptw_64_s1(SMMUState *bs, SMMUTransCfg = *cfg, goto error; } =20 + if (current_ns) { + cur_sec_sid =3D SMMU_SEC_SID_NS; + } else { + cur_sec_sid =3D PTE_NS(pte) ? SMMU_SEC_SID_NS : SMMU_SEC_SID_S; + } + tlbe->entry.target_as =3D smmu_get_address_space(bs, cur_sec_sid); tlbe->entry.translated_addr =3D gpa; tlbe->entry.iova =3D iova & ~mask; tlbe->entry.addr_mask =3D mask; @@ -697,7 +736,10 @@ static int smmu_ptw_64_s2(SMMUState *bs, SMMUTransCfg = *cfg, uint64_t pte, gpa; dma_addr_t pte_addr =3D baseaddr + offset * sizeof(pte); uint8_t s2ap; - if (get_pte(baseaddr, offset, &pte, info)) { + AddressSpace *pte_as =3D &bs->memory_as; + MemTxAttrs pte_attrs =3D MEMTXATTRS_UNSPECIFIED; + + if (get_pte(baseaddr, offset, &pte, info, pte_as, pte_attrs)) { goto error; } trace_smmu_ptw_level(stage, level, ipa, subpage_size, @@ -792,7 +834,7 @@ static void combine_tlb(SMMUTLBEntry *tlbe, SMMUTLBEntr= y *tlbe_s2, } =20 /** - * smmu_ptw - Walk the page tables for an IOVA, according to @cfg + * smmu_ptw - Walk the page tables for an IOVA, according to @cfg and @sec= _sid * * @bs: smmu state which includes TLB instance * @cfg: translation configuration @@ -800,18 +842,20 @@ static void combine_tlb(SMMUTLBEntry *tlbe, SMMUTLBEn= try *tlbe_s2, * @perm: tentative access type * @tlbe: returned entry * @info: ptw event handle + * @sec_sid: StreamID Security state * * return 0 on success */ int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t iova, - IOMMUAccessFlags perm, SMMUTLBEntry *tlbe, SMMUPTWEventInfo *= info) + IOMMUAccessFlags perm, SMMUTLBEntry *tlbe, SMMUPTWEventInfo *= info, + SMMUSecSID sec_sid) { int ret; SMMUTLBEntry tlbe_s2; dma_addr_t ipa; =20 if (cfg->stage =3D=3D SMMU_STAGE_1) { - return smmu_ptw_64_s1(bs, cfg, iova, perm, tlbe, info); + return smmu_ptw_64_s1(bs, cfg, iova, perm, tlbe, info, sec_sid); } else if (cfg->stage =3D=3D SMMU_STAGE_2) { /* * If bypassing stage 1(or unimplemented), the input address is pa= ssed @@ -830,7 +874,7 @@ int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr= _t iova, } =20 /* SMMU_NESTED. */ - ret =3D smmu_ptw_64_s1(bs, cfg, iova, perm, tlbe, info); + ret =3D smmu_ptw_64_s1(bs, cfg, iova, perm, tlbe, info, sec_sid); if (ret) { return ret; } @@ -846,7 +890,8 @@ int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr= _t iova, } =20 SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t = addr, - IOMMUAccessFlags flag, SMMUPTWEventInfo *info) + IOMMUAccessFlags flag, SMMUPTWEventInfo *info, + SMMUSecSID sec_sid) { SMMUTLBEntry *cached_entry =3D NULL; SMMUTransTableInfo *tt; @@ -888,7 +933,7 @@ SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCf= g *cfg, dma_addr_t addr, } =20 cached_entry =3D g_new0(SMMUTLBEntry, 1); - status =3D smmu_ptw(bs, cfg, addr, flag, cached_entry, info); + status =3D smmu_ptw(bs, cfg, addr, flag, cached_entry, info, sec_sid); if (status) { g_free(cached_entry); return NULL; diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 6b34f76f11b..cc5d3ab696c 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -394,7 +394,8 @@ static SMMUTranslationStatus smmuv3_do_translate(SMMUv3= State *s, hwaddr addr, SMMUEventInfo *event, IOMMUAccessFlags flag, SMMUTLBEntry **out_entry, - SMMUTranslationClass clas= s); + SMMUTranslationClass clas= s, + SMMUSecSID sec_sid); /* @ssid > 0 not supported yet */ static int smmu_get_cd(SMMUv3State *s, STE *ste, SMMUTransCfg *cfg, uint32_t ssid, CD *buf, SMMUEventInfo *event, @@ -411,7 +412,7 @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, SMMUTr= ansCfg *cfg, =20 if (cfg->stage =3D=3D SMMU_NESTED) { status =3D smmuv3_do_translate(s, addr, cfg, event, - IOMMU_RO, &entry, SMMU_CLASS_CD); + IOMMU_RO, &entry, SMMU_CLASS_CD, sec_= sid); =20 /* Same PTW faults are reported but with CLASS =3D CD. */ if (status !=3D SMMU_TRANS_SUCCESS) { @@ -796,7 +797,7 @@ int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *st= e, SMMUEventInfo *event, } =20 static int decode_cd(SMMUv3State *s, SMMUTransCfg *cfg, - CD *cd, SMMUEventInfo *event) + CD *cd, SMMUEventInfo *event, SMMUSecSID sec_sid) { int ret =3D -EINVAL; int i; @@ -869,7 +870,7 @@ static int decode_cd(SMMUv3State *s, SMMUTransCfg *cfg, /* Translate the TTBx, from IPA to PA if nesting is enabled. */ if (cfg->stage =3D=3D SMMU_NESTED) { status =3D smmuv3_do_translate(s, tt->ttb, cfg, event, IOMMU_R= O, - &entry, SMMU_CLASS_TT); + &entry, SMMU_CLASS_TT, sec_sid); /* * Same PTW faults are reported but with CLASS =3D TT. * If TTBx is larger than the effective stage 1 output addres @@ -939,7 +940,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, = SMMUTransCfg *cfg, return ret; } =20 - return decode_cd(s, cfg, &cd, event); + return decode_cd(s, cfg, &cd, event, sec_sid); } =20 /** @@ -1004,7 +1005,8 @@ static SMMUTranslationStatus smmuv3_do_translate(SMMU= v3State *s, hwaddr addr, SMMUEventInfo *event, IOMMUAccessFlags flag, SMMUTLBEntry **out_entry, - SMMUTranslationClass clas= s) + SMMUTranslationClass clas= s, + SMMUSecSID sec_sid) { SMMUPTWEventInfo ptw_info =3D {}; SMMUState *bs =3D ARM_SMMU(s); @@ -1030,7 +1032,7 @@ static SMMUTranslationStatus smmuv3_do_translate(SMMU= v3State *s, hwaddr addr, cfg->stage =3D SMMU_STAGE_2; } =20 - cached_entry =3D smmu_translate(bs, cfg, addr, flag, &ptw_info); + cached_entry =3D smmu_translate(bs, cfg, addr, flag, &ptw_info, sec_si= d); =20 if (desc_s2_translation) { cfg->asid =3D asid; @@ -1176,13 +1178,14 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRe= gion *mr, hwaddr addr, } =20 status =3D smmuv3_do_translate(s, addr, cfg, &event, flag, - &cached_entry, SMMU_CLASS_IN); + &cached_entry, SMMU_CLASS_IN, sec_sid); =20 epilogue: qemu_mutex_unlock(&s->mutex); switch (status) { case SMMU_TRANS_SUCCESS: entry.perm =3D cached_entry->entry.perm; + entry.target_as =3D cached_entry->entry.target_as; entry.translated_addr =3D CACHED_ENTRY_TO_ADDR(cached_entry, addr); entry.addr_mask =3D cached_entry->entry.addr_mask; trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr, diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 1aa4e3208da..0c5718ea684 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -224,18 +224,19 @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev) =20 /** * smmu_ptw - Perform the page table walk for a given iova / access flags - * pair, according to @cfg translation config + * pair, according to @cfg translation config and @sec_sid */ int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm, SMMUTLBEntry *tlbe, - SMMUPTWEventInfo *info); + SMMUPTWEventInfo *info, SMMUSecSID sec_sid); =20 /* * smmu_translate - Look for a translation in TLB, if not, do a PTW. * Returns NULL on PTW error or incase of TLB permission errors. */ SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t = addr, - IOMMUAccessFlags flag, SMMUPTWEventInfo *info= ); + IOMMUAccessFlags flag, SMMUPTWEventInfo *info, + SMMUSecSID sec_sid); =20 /** * select_tt - compute which translation table shall be used according to --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638589293681.8434583214444; Thu, 13 Aug 2026 09:29:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFA-0001JA-Mb; Thu, 13 Aug 2026 12:25:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYF8-000191-QA; Thu, 13 Aug 2026 12:25:23 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYF5-000107-Cd; Thu, 13 Aug 2026 12:25:22 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwD3oMjs731qwFDmAA--.20461S2; Fri, 14 Aug 2026 00:25:16 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBnPo731q5SwjAA--.54277S4; Fri, 14 Aug 2026 00:25: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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 12/28] hw/arm/smmuv3: Tag IOTLB cache keys with SEC_SID Date: Fri, 14 Aug 2026 00:25:09 +0800 Message-Id: <20260813162512.2807281-2-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBnPo731q5SwjAA--.54277S4 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HnwAAsI Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoWfZw17trWkJF1UGF17Gr15Arb_yoW8KFWfKo WfG3WFqr48X3W3u3WqkF4xJa42vayDtay5Zw45X3yYg3ZxKrs8tFWxKr4fXF4FqF4UAF40 9F95JFW8XFyUCr93n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXasCq-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=lists1p.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, 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: 1786638591599158500 Content-Type: text/plain; charset="utf-8" To prevent aliasing between translations controlled through the Secure and Non-secure programming interfaces, the IOTLB lookup key must incorporate SEC_SID. This commit: - expands SMMUIOTLBKey with SEC_SID field for cache key differentiation - extends SMMUIOTLBPageInvInfo with SEC_SID for invalidation filtering - updates all IOTLB invalidation helpers (smmu_iotlb_inv_iova, smmu_iotlb_inv_ipa, smmu_iotlb_inv_asid_vmid, smmu_iotlb_inv_vmid, smmu_iotlb_inv_vmid_s1) to accept and filter by SEC_SID - plumbs SEC_SID through smmuv3_range_inval for TLB invalidation - enhances trace events to include SEC_SID for better debugging This ensures that IOTLB entries decoded through the Secure and Non-secure programming interfaces are distinct, preventing cache aliasing across SEC_SID namespaces. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 110 +++++++++++++++++++++++------------ hw/arm/smmu-internal.h | 2 + hw/arm/smmuv3.c | 47 ++++++++++----- hw/arm/trace-events | 20 +++---- include/hw/arm/smmu-common.h | 32 +++++++--- 5 files changed, 140 insertions(+), 71 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 317cfafded2..3d4b6b3a287 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -95,7 +95,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 @@ -111,14 +111,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; } @@ -126,7 +127,8 @@ SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uin= t64_t iova, static SMMUTLBEntry *smmu_iotlb_lookup_all_levels(SMMUState *bs, SMMUTransCfg *cfg, SMMUTransTableInfo *tt, - hwaddr iova) + hwaddr iova, + SMMUSecSID sec_sid) { uint8_t tg =3D (tt->granule_sz - 10) / 2; uint8_t inputsize =3D 64 - tt->tsz; @@ -140,7 +142,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, sec_sid); entry =3D g_hash_table_lookup(bs->iotlb, &key); if (entry) { break; @@ -156,6 +158,7 @@ static SMMUTLBEntry *smmu_iotlb_lookup_all_levels(SMMUS= tate *bs, * @cfg: Configuration of the translation * @tt: Translation table info (granule and tsz) * @iova: IOVA address to lookup + * @sec_sid: StreamID Security state * * returns a valid entry on success, otherwise NULL. * In case of nested translation, tt can be updated to include @@ -163,11 +166,12 @@ static SMMUTLBEntry *smmu_iotlb_lookup_all_levels(SMM= UState *bs, * the IOVA granule. */ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg, - SMMUTransTableInfo *tt, hwaddr iova) + SMMUTransTableInfo *tt, hwaddr iova, + SMMUSecSID sec_sid) { SMMUTLBEntry *entry =3D NULL; =20 - entry =3D smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova); + entry =3D smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova, sec_sid); /* * For nested translation also try the s2 granule, as the TLB will ins= ert * it if the size of s2 tlb entry was smaller. @@ -175,18 +179,20 @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTr= ansCfg *cfg, if (!entry && (cfg->stage =3D=3D SMMU_NESTED) && (cfg->s2cfg.granule_sz !=3D tt->granule_sz)) { tt->granule_sz =3D cfg->s2cfg.granule_sz; - entry =3D smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova); + entry =3D smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova, sec_sid); } =20 if (entry) { cfg->iotlb_hits++; - trace_smmu_iotlb_lookup_hit(cfg->asid, cfg->s2cfg.vmid, iova, + trace_smmu_iotlb_lookup_hit(sec_sid, cfg->asid, + cfg->s2cfg.vmid, iova, cfg->iotlb_hits, cfg->iotlb_misses, 100 * cfg->iotlb_hits / (cfg->iotlb_hits + cfg->iotlb_misses)); } else { cfg->iotlb_misses++; - trace_smmu_iotlb_lookup_miss(cfg->asid, cfg->s2cfg.vmid, iova, + trace_smmu_iotlb_lookup_miss(sec_sid, cfg->asid, + cfg->s2cfg.vmid, iova, cfg->iotlb_hits, cfg->iotlb_misses, 100 * cfg->iotlb_hits / (cfg->iotlb_hits + cfg->iotlb_misses)= ); @@ -194,7 +200,8 @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTran= sCfg *cfg, return entry; } =20 -void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new) +void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new, + SMMUSecSID sec_sid) { SMMUIOTLBKey *key =3D g_new0(SMMUIOTLBKey, 1); uint8_t tg =3D (new->granule - 10) / 2; @@ -204,9 +211,9 @@ 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); - trace_smmu_iotlb_insert(cfg->asid, cfg->s2cfg.vmid, new->entry.iova, - tg, new->level); + tg, new->level, sec_sid); + trace_smmu_iotlb_insert(sec_sid, cfg->asid, cfg->s2cfg.vmid, + new->entry.iova, tg, new->level); g_hash_table_insert(bs->iotlb, key, new); } =20 @@ -223,26 +230,29 @@ static gboolean smmu_hash_remove_by_asid_vmid(gpointe= r key, gpointer value, SMMUIOTLBKey *iotlb_key =3D (SMMUIOTLBKey *)key; =20 return (SMMU_IOTLB_ASID(*iotlb_key) =3D=3D info->asid) && - (SMMU_IOTLB_VMID(*iotlb_key) =3D=3D info->vmid); + (SMMU_IOTLB_VMID(*iotlb_key) =3D=3D info->vmid) && + (SMMU_IOTLB_SEC_SID(*iotlb_key) =3D=3D info->sec_sid); } =20 static gboolean smmu_hash_remove_by_vmid(gpointer key, gpointer value, gpointer user_data) { - int vmid =3D *(int *)user_data; + SMMUIOTLBPageInvInfo *info =3D (SMMUIOTLBPageInvInfo *)user_data; SMMUIOTLBKey *iotlb_key =3D (SMMUIOTLBKey *)key; =20 - return SMMU_IOTLB_VMID(*iotlb_key) =3D=3D vmid; + return (SMMU_IOTLB_VMID(*iotlb_key) =3D=3D info->vmid) && + (SMMU_IOTLB_SEC_SID(*iotlb_key) =3D=3D info->sec_sid); } =20 static gboolean smmu_hash_remove_by_vmid_s1(gpointer key, gpointer value, gpointer user_data) { - int vmid =3D *(int *)user_data; + SMMUIOTLBPageInvInfo *info =3D (SMMUIOTLBPageInvInfo *)user_data; SMMUIOTLBKey *iotlb_key =3D (SMMUIOTLBKey *)key; =20 - return (SMMU_IOTLB_VMID(*iotlb_key) =3D=3D vmid) && - (SMMU_IOTLB_ASID(*iotlb_key) >=3D 0); + return (SMMU_IOTLB_VMID(*iotlb_key) =3D=3D info->vmid) && + (SMMU_IOTLB_ASID(*iotlb_key) >=3D 0) && + (SMMU_IOTLB_SEC_SID(*iotlb_key) =3D=3D info->sec_sid); } =20 static gboolean smmu_hash_remove_by_asid_vmid_iova(gpointer key, gpointer = value, @@ -259,6 +269,9 @@ static gboolean smmu_hash_remove_by_asid_vmid_iova(gpoi= nter key, gpointer value, if (info->vmid >=3D 0 && info->vmid !=3D SMMU_IOTLB_VMID(iotlb_key)) { return false; } + if (info->sec_sid !=3D SMMU_IOTLB_SEC_SID(iotlb_key)) { + return false; + } return ((info->iova & ~entry->addr_mask) =3D=3D entry->iova) || ((entry->iova & ~info->mask) =3D=3D info->iova); } @@ -278,6 +291,9 @@ static gboolean smmu_hash_remove_by_vmid_ipa(gpointer k= ey, gpointer value, if (info->vmid !=3D SMMU_IOTLB_VMID(iotlb_key)) { return false; } + if (info->sec_sid !=3D SMMU_IOTLB_SEC_SID(iotlb_key)) { + return false; + } return ((info->iova & ~entry->addr_mask) =3D=3D entry->iova) || ((entry->iova & ~info->mask) =3D=3D info->iova); } @@ -323,13 +339,17 @@ 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 + trace_smmu_iotlb_inv_iova(sec_sid, asid, iova); + 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; @@ -343,7 +363,8 @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vm= id, dma_addr_t iova, SMMUIOTLBPageInvInfo info =3D { .asid =3D asid, .iova =3D iova, .vmid =3D vmid, - .mask =3D (num_pages * 1 << granule) - 1}; + .mask =3D (num_pages * 1 << granule) - 1, + .sec_sid =3D sec_sid}; =20 g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid_vmid_iova, @@ -355,13 +376,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; @@ -371,34 +394,47 @@ void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_a= ddr_t ipa, uint8_t tg, SMMUIOTLBPageInvInfo info =3D { .iova =3D ipa, .vmid =3D vmid, - .mask =3D (num_pages << granule) - 1}; + .mask =3D (num_pages << granule) - 1, + .sec_sid =3D sec_sid}; =20 g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid_ipa, &info); } =20 -void smmu_iotlb_inv_asid_vmid(SMMUState *s, int asid, int vmid) +void smmu_iotlb_inv_asid_vmid(SMMUState *s, int asid, int vmid, + SMMUSecSID sec_sid) { SMMUIOTLBPageInvInfo info =3D { .asid =3D asid, .vmid =3D vmid, + .sec_sid =3D sec_sid, }; =20 - trace_smmu_iotlb_inv_asid_vmid(asid, vmid); + trace_smmu_iotlb_inv_asid_vmid(sec_sid, asid, vmid); g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid_vmid, &= info); } =20 -void smmu_iotlb_inv_vmid(SMMUState *s, int vmid) +void smmu_iotlb_inv_vmid(SMMUState *s, int vmid, SMMUSecSID sec_sid) { - trace_smmu_iotlb_inv_vmid(vmid); - g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid, &vmid); + SMMUIOTLBPageInvInfo info =3D { + .vmid =3D vmid, + .sec_sid =3D sec_sid, + }; + + trace_smmu_iotlb_inv_vmid(sec_sid, vmid); + g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid, &info); } =20 -void smmu_iotlb_inv_vmid_s1(SMMUState *s, int vmid) +void smmu_iotlb_inv_vmid_s1(SMMUState *s, int vmid, SMMUSecSID sec_sid) { - trace_smmu_iotlb_inv_vmid_s1(vmid); - g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid_s1, &vm= id); + SMMUIOTLBPageInvInfo info =3D { + .vmid =3D vmid, + .sec_sid =3D sec_sid, + }; + + trace_smmu_iotlb_inv_vmid_s1(sec_sid, vmid); + g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid_s1, &in= fo); } =20 /* VMSAv8-64 Translation */ @@ -919,7 +955,7 @@ SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCf= g *cfg, dma_addr_t addr, tt_combined.tsz =3D tt->tsz; } =20 - cached_entry =3D smmu_iotlb_lookup(bs, cfg, &tt_combined, addr); + cached_entry =3D smmu_iotlb_lookup(bs, cfg, &tt_combined, addr, sec_si= d); if (cached_entry) { if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & cached_entry->parent_perm & IOMMU_WO)) { @@ -938,7 +974,7 @@ SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCf= g *cfg, dma_addr_t addr, g_free(cached_entry); return NULL; } - smmu_iotlb_insert(bs, cfg, cached_entry); + smmu_iotlb_insert(bs, cfg, cached_entry, sec_sid); return cached_entry; } =20 diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h index 004abd58bca..ce68d4b5813 100644 --- a/hw/arm/smmu-internal.h +++ b/hw/arm/smmu-internal.h @@ -144,12 +144,14 @@ static inline int pgd_concat_idx(int start_level, int= granule_sz, =20 #define SMMU_IOTLB_ASID(key) ((key).asid) #define SMMU_IOTLB_VMID(key) ((key).vmid) +#define SMMU_IOTLB_SEC_SID(key) ((key).sec_sid) =20 typedef struct SMMUIOTLBPageInvInfo { int asid; int vmid; uint64_t iova; uint64_t mask; + SMMUSecSID sec_sid; } SMMUIOTLBPageInvInfo; =20 #endif diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index cc5d3ab696c..087112ba4b6 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -634,6 +634,17 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cf= g, goto bad_ste; } =20 + /* + * Keep the SEC_SID-to-StreamWorld approximation used by the IOTLB key + * one-to-one until the other Secure translation regimes are modeled. + */ + if (sec_sid =3D=3D SMMU_SEC_SID_S && STE_CFG_S1_TRANSLATE(config) && + STE_STRW(ste) !=3D 0) { + qemu_log_mask(LOG_UNIMP, + "SMMUv3 Secure StreamWorld is not implemented\n"); + goto bad_ste; + } + if (STAGE2_SUPPORTED(s)) { /* VMID is considered even if s2 is disabled. */ cfg->s2cfg.vmid =3D STE_S2VMID(ste); @@ -1317,7 +1328,8 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, i= nt asid, int vmid, } } =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); @@ -1342,12 +1354,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= ); + 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); 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; } @@ -1364,13 +1377,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); 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; } @@ -1521,9 +1536,9 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) vmid =3D CMD_VMID(&cmd); } =20 - trace_smmuv3_cmdq_tlbi_nh_asid(asid); + trace_smmuv3_cmdq_tlbi_nh_asid(sec_sid, asid); smmu_inv_notifiers_all(&s->smmu_state); - smmu_iotlb_inv_asid_vmid(bs, asid, vmid); + smmu_iotlb_inv_asid_vmid(bs, asid, vmid, sec_sid); if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { cmd_error =3D SMMU_CERROR_ILL; break; @@ -1545,8 +1560,8 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) */ if (STAGE2_SUPPORTED(s)) { vmid =3D CMD_VMID(&cmd); - trace_smmuv3_cmdq_tlbi_nh(vmid); - smmu_iotlb_inv_vmid_s1(bs, vmid); + trace_smmuv3_cmdq_tlbi_nh(sec_sid, vmid); + smmu_iotlb_inv_vmid_s1(bs, vmid, sec_sid); break; } QEMU_FALLTHROUGH; @@ -1566,7 +1581,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) 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); if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { cmd_error =3D SMMU_CERROR_ILL; break; @@ -1583,7 +1598,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) =20 trace_smmuv3_cmdq_tlbi_s12_vmid(vmid); smmu_inv_notifiers_all(&s->smmu_state); - smmu_iotlb_inv_vmid(bs, vmid); + smmu_iotlb_inv_vmid(bs, vmid, SMMU_SEC_SID_NS); break; } case SMMU_CMD_TLBI_S2_IPA: @@ -1595,7 +1610,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp) * 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_ATC_INV: { diff --git a/hw/arm/trace-events b/hw/arm/trace-events index a166b79c8ef..6a8716e8041 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -19,16 +19,16 @@ smmu_ptw_page_pte(int stage, int level, uint64_t iova,= uint64_t baseaddr, uint6 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_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" -smmu_iotlb_inv_vmid_s1(int vmid) "IOTLB invalidate vmid=3D%d" -smmu_iotlb_inv_iova(int asid, uint64_t addr) "IOTLB invalidate asid=3D%d a= ddr=3D0x%"PRIx64 +smmu_iotlb_inv_asid_vmid(int sec_sid, int asid, int vmid) "IOTLB invalidat= e sec_sid=3D%d asid=3D%d vmid=3D%d" +smmu_iotlb_inv_vmid(int sec_sid, int vmid) "IOTLB invalidate sec_sid=3D%d = vmid=3D%d" +smmu_iotlb_inv_vmid_s1(int sec_sid, int vmid) "IOTLB invalidate S1 sec_sid= =3D%d vmid=3D%d" +smmu_iotlb_inv_iova(int sec_sid, int asid, uint64_t addr) "IOTLB invalidat= e sec_sid=3D%d asid=3D%d addr=3D0x%"PRIx64 smmu_configs_inv_sid_range(uint32_t start, uint32_t end) "Config cache INV= SID range from 0x%x to 0x%x" smmu_config_cache_inv(uint32_t sid) "Config cache INV for sid=3D0x%x" smmu_inv_notifiers_mr(const char *name) "iommu mr=3D%s" -smmu_iotlb_lookup_hit(int asid, int vmid, uint64_t addr, uint32_t hit, uin= t32_t miss, uint32_t p) "IOTLB cache HIT asid=3D%d vmid=3D%d addr=3D0x%"PRI= x64" hit=3D%d miss=3D%d hit rate=3D%d" -smmu_iotlb_lookup_miss(int asid, int vmid, uint64_t addr, uint32_t hit, ui= nt32_t miss, uint32_t p) "IOTLB cache MISS asid=3D%d vmid=3D%d addr=3D0x%"P= RIx64" hit=3D%d miss=3D%d hit rate=3D%d" -smmu_iotlb_insert(int asid, int vmid, uint64_t addr, uint8_t tg, uint8_t l= evel) "IOTLB ++ asid=3D%d vmid=3D%d addr=3D0x%"PRIx64" tg=3D%d level=3D%d" +smmu_iotlb_lookup_hit(int sec_sid, int asid, int vmid, uint64_t addr, uint= 32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT sec_sid=3D%d asid=3D%= d vmid=3D%d addr=3D0x%"PRIx64" hit=3D%d miss=3D%d hit rate=3D%d" +smmu_iotlb_lookup_miss(int sec_sid, int asid, int vmid, uint64_t addr, uin= t32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS sec_sid=3D%d asid= =3D%d vmid=3D%d addr=3D0x%"PRIx64" hit=3D%d miss=3D%d hit rate=3D%d" +smmu_iotlb_insert(int sec_sid, int asid, int vmid, uint64_t addr, uint8_t = tg, uint8_t level) "IOTLB ++ sec_sid=3D%d asid=3D%d vmid=3D%d addr=3D0x%"PR= Ix64" tg=3D%d level=3D%d" =20 # smmuv3.c smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "= addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)" @@ -57,10 +57,10 @@ smmuv3_cmdq_cfgi_ste_range(int start, int end) "start= =3D0x%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_cmdq_tlbi_nh(int vmid) "vmid=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 sec_sid, int vmid) "sec_sid=3D%d vmid=3D%d" smmuv3_cmdq_tlbi_nsnh(void) "" -smmuv3_cmdq_tlbi_nh_asid(int asid) "asid=3D%d" +smmuv3_cmdq_tlbi_nh_asid(int sec_sid, int asid) "sec_sid=3D%d asid=3D%d" 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" diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 0c5718ea684..8e971c28093 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -152,6 +152,17 @@ typedef struct SMMUIOTLBKey { int vmid; uint8_t tg; uint8_t level; + /* + * We currently model one StreamWorld per SEC_SID, giving the approxim= ate + * mapping: + * + * SMMU_SEC_SID_NS -> NS-EL1 + * SMMU_SEC_SID_S -> Secure + * + * SEC_SID is not architecturally equivalent to StreamWorld. Extend th= is + * key when additional translation regimes are implemented. + */ + SMMUSecSID sec_sid; } SMMUIOTLBKey; =20 typedef struct SMMUConfigKey { @@ -250,19 +261,24 @@ SMMUDevice *smmu_find_sdev(SMMUState *s, uint32_t sid= ); #define SMMU_IOTLB_MAX_SIZE 256 =20 SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg, - SMMUTransTableInfo *tt, hwaddr iova); -void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *ent= ry); + SMMUTransTableInfo *tt, hwaddr iova, + SMMUSecSID sec_sid); +void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *ent= ry, + SMMUSecSID sec_sid); 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_asid_vmid(SMMUState *s, int asid, int vmid, + SMMUSecSID sec_sid); +void smmu_iotlb_inv_vmid(SMMUState *s, int vmid, SMMUSecSID sec_sid); +void smmu_iotlb_inv_vmid_s1(SMMUState *s, int vmid, SMMUSecSID sec_sid); 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 Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638371844191.84037081502015; Thu, 13 Aug 2026 09:26:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYF9-0001Bo-KE; Thu, 13 Aug 2026 12:25:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYF6-0000zy-Os; Thu, 13 Aug 2026 12:25:20 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYF4-0000zn-SD; Thu, 13 Aug 2026 12:25:20 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwA3Pvbs731qvVDmAA--.4962S2; Fri, 14 Aug 2026 00:25:16 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBnPo731q5SwjAA--.54277S5; Fri, 14 Aug 2026 00:25:15 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 13/28] hw/arm/smmuv3: Pass sec_sid into cmdq consume path Date: Fri, 14 Aug 2026 00:25:10 +0800 Message-Id: <20260813162512.2807281-3-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBnPo731q5SwjAA--.54277S5 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HnwABsJ Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxtFW3uF15KrWDAFW8XFyUGFg_yoWxXFyxpr WDJ3sI9r18X3Z3ZF9Fv3y8ur13J34DtFy3tr1UW3Wfu3WDAr15Xrs8Kr1ru34DGryxAws3 XayfWan8Z3W2y37anT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638372358158500 Content-Type: text/plain; charset="utf-8" Make smmuv3_cmdq_consume() security-state aware by passing sec_sid from smmu_writel() call sites (CR0/GERRORN/CMDQ_PROD paths), instead of hardcoding non-secure state. The related AddressSpace and MemTxAttrs are also obtained based on sec_sid. Also move CMD_SSEC legality checking to a single early check before command dispatch: secure commands are rejected on non-secure queues (including future Realm queue) with CERROR_ILL. This removes duplicated per-command checks in CFGI handlers. Finally, extend cmdq trace output with sec_sid so command processing can be correlated with the correct security bank. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 47 +++++++++++++++++++++------------------------ hw/arm/trace-events | 2 +- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 087112ba4b6..fa13191fc3b 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -112,14 +112,14 @@ static void smmuv3_write_gerrorn(SMMUv3State *s, uint= 32_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, + AddressSpace *as, MemTxAttrs attrs) { dma_addr_t addr =3D Q_CONS_ENTRY(q); MemTxResult ret; int i; =20 - ret =3D dma_memory_read(&address_space_memory, addr, cmd, sizeof(Cmd), - MEMTXATTRS_UNSPECIFIED); + ret =3D dma_memory_read(as, addr, cmd, sizeof(Cmd), attrs); if (ret !=3D MEMTX_OK) { return ret; } @@ -1391,14 +1391,15 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *c= md, SMMUStage stage, } } =20 -static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp) +static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp, SMMUSecSID se= c_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; + MemTxAttrs attrs =3D smmu_get_txattrs(sec_sid); + AddressSpace *as =3D smmu_get_address_space(bs, sec_sid); =20 if (!smmuv3_cmdq_enabled(s, sec_sid)) { return 0; @@ -1413,19 +1414,30 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Erro= r **errp) while (!smmuv3_q_empty(q)) { uint32_t pending =3D bank->gerror ^ bank->gerrorn; Cmd cmd; + SMMUSecSID ssec =3D SMMU_SEC_SID_NS; =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, as, attrs) !=3D MEMTX_OK) { cmd_error =3D SMMU_CERROR_ABT; break; } =20 + ssec =3D CMD_SSEC(&cmd) ? SMMU_SEC_SID_S : SMMU_SEC_SID_NS; + /* + * A command with SSec =3D=3D 1 is illegal on Non-secure and Realm= Command + * queues and raises CERROR_ILL, as specified by (IHI 0070G.b) 4.1= .6. + */ + if (ssec && sec_sid !=3D SMMU_SEC_SID_S) { + cmd_error =3D SMMU_CERROR_ILL; + break; + } + type =3D CMD_TYPE(&cmd); =20 trace_smmuv3_cmdq_opcode(smmu_cmd_string(type)); @@ -1445,11 +1457,6 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error= **errp) uint32_t sid =3D CMD_SID(&cmd); SMMUDevice *sdev =3D smmu_find_sdev(bs, sid); =20 - if (CMD_SSEC(&cmd)) { - cmd_error =3D SMMU_CERROR_ILL; - break; - } - if (!sdev) { break; } @@ -1469,11 +1476,6 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error= **errp) uint8_t range =3D CMD_STE_RANGE(&cmd); SMMUSIDRange sid_range; =20 - if (CMD_SSEC(&cmd)) { - cmd_error =3D SMMU_CERROR_ILL; - break; - } - mask =3D (1ULL << (range + 1)) - 1; sid_range.start =3D sid & ~mask; sid_range.end =3D sid_range.start + mask; @@ -1492,11 +1494,6 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error= **errp) uint32_t sid =3D CMD_SID(&cmd); SMMUDevice *sdev =3D smmu_find_sdev(bs, sid); =20 - if (CMD_SSEC(&cmd)) { - cmd_error =3D SMMU_CERROR_ILL; - break; - } - if (!sdev) { break; } @@ -1720,7 +1717,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, &local_err); + smmuv3_cmdq_consume(s, &local_err, reg_sec_sid); if (local_err) { error_report_err(local_err); local_err =3D NULL; @@ -1743,7 +1740,7 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr= offset, * By acknowledging the CMDQ_ERR, SW may notify cmds can * be processed again */ - smmuv3_cmdq_consume(s, &local_err); + smmuv3_cmdq_consume(s, &local_err, reg_sec_sid); break; case A_GERROR_IRQ_CFG0: /* 64b */ bank->gerror_irq_cfg0 =3D deposit64(bank->gerror_irq_cfg0, 0, 32, = data); @@ -1801,7 +1798,7 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr= offset, break; case A_CMDQ_PROD: bank->cmdq.prod =3D data; - smmuv3_cmdq_consume(s, &local_err); + smmuv3_cmdq_consume(s, &local_err, reg_sec_sid); break; case A_CMDQ_CONS: bank->cmdq.cons =3D data; diff --git a/hw/arm/trace-events b/hw/arm/trace-events index 6a8716e8041..ccc0ab50164 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -36,7 +36,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 Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638443987894.1101690148236; Thu, 13 Aug 2026 09:27:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFA-0001JI-Ng; Thu, 13 Aug 2026 12:25:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYF8-00016n-C0; Thu, 13 Aug 2026 12:25:22 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYF5-00010G-Vn; Thu, 13 Aug 2026 12:25:22 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwBnbLTt731qxVDmAA--.5018S2; Fri, 14 Aug 2026 00:25:17 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBnPo731q5SwjAA--.54277S6; Fri, 14 Aug 2026 00:25:16 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 14/28] hw/arm/smmuv3: Make evtq producer use SEC_SID Date: Fri, 14 Aug 2026 00:25:11 +0800 Message-Id: <20260813162512.2807281-4-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBnPo731q5SwjAA--.54277S6 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HoQAAs2 Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7ZF4xAFy7XF1rXF4xXw4rAFb_yoW8ZF43pr Wqkwn5K34YyFsxJF95Zrs5u3W7u3yIqr9rGrWxKFy5uw1UAw43XF1UKryFyryvqr97J3y5 ZFWfCay5Zr45t3DanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638444553158500 Content-Type: text/plain; charset="utf-8" The event queue producer path wrote entries through address_space_memory with MEMTXATTRS_UNSPECIFIED, so produced entries did not use the sec_sid-selected DMA context. Pass AddressSpace and MemTxAttrs to queue_write() based on sec_sid. Signed-off-by: Tao Tang Reviewed-by: Eric Auger Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index fa13191fc3b..7e08b88689f 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -129,7 +129,8 @@ static inline MemTxResult queue_read(SMMUQueue *q, Cmd = *cmd, return ret; } =20 -static MemTxResult queue_write(SMMUQueue *q, Evt *evt_in) +static MemTxResult queue_write(SMMUQueue *q, Evt *evt_in, + AddressSpace *as, MemTxAttrs attrs) { dma_addr_t addr =3D Q_PROD_ENTRY(q); MemTxResult ret; @@ -139,8 +140,7 @@ static MemTxResult queue_write(SMMUQueue *q, Evt *evt_i= n) for (i =3D 0; i < ARRAY_SIZE(evt.word); i++) { cpu_to_le32s(&evt.word[i]); } - ret =3D dma_memory_write(&address_space_memory, addr, &evt, sizeof(Evt= ), - MEMTXATTRS_UNSPECIFIED); + ret =3D dma_memory_write(as, addr, &evt, sizeof(Evt), attrs); if (ret !=3D MEMTX_OK) { return ret; } @@ -155,6 +155,9 @@ static MemTxResult smmuv3_write_eventq(SMMUv3State *s, = SMMUSecSID sec_sid, SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); SMMUQueue *q =3D &bank->eventq; MemTxResult r; + SMMUState *bs =3D ARM_SMMU(s); + MemTxAttrs txattrs =3D smmu_get_txattrs(sec_sid); + AddressSpace *as =3D smmu_get_address_space(bs, sec_sid); =20 if (!smmuv3_eventq_enabled(s, sec_sid)) { return MEMTX_ERROR; @@ -164,7 +167,7 @@ static MemTxResult smmuv3_write_eventq(SMMUv3State *s, = SMMUSecSID sec_sid, return MEMTX_ERROR; } =20 - r =3D queue_write(q, evt); + r =3D queue_write(q, evt, as, txattrs); if (r !=3D MEMTX_OK) { return r; } --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638515281512.1912544618731; Thu, 13 Aug 2026 09:28:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFD-0001WA-2H; Thu, 13 Aug 2026 12:25:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYFB-0001Ow-Fo; Thu, 13 Aug 2026 12:25:25 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYF8-000115-2D; Thu, 13 Aug 2026 12:25:25 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwAnLLTv731qzFDmAA--.5032S2; Fri, 14 Aug 2026 00:25:19 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBnPo731q5SwjAA--.54277S7; Fri, 14 Aug 2026 00:25:16 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 15/28] hw/arm/smmu: Make CMDQ invalidation security-state aware Date: Fri, 14 Aug 2026 00:25:12 +0800 Message-Id: <20260813162512.2807281-5-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBnPo731q5SwjAA--.54277S7 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HpAAAsz Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoWfWF43tr45CFy7trWkZw1fZwb_yoW5JFy3Wo WrJr4Ygr48Xr1agFn2vw1kGFZ7ZryDtayUWw45X3yag3ZxtF15XFy8tFZ8Xa1YyF4UXFZY vF95GrZ7XFyUAF1rn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXasCq-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=lists1p.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, 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: 1786638517412158500 Content-Type: text/plain; charset="utf-8" Refactor CMDQ invalidation paths to carry security state and apply cache invalidation per sec_sid instead of globally. Add separate helpers for invalidating all entries and for invalidating entries belonging to one valid sec_sid. In smmuv3, propagate the command queue sec_sid and command SSec through CFGI and TLBI handling, and gate VMID use on the stage-2 capability of the selected command queue, including SMMU_S_IDR1.SEL2 for a Secure Command queue. Keep acceleration and IOMMU notifier propagation Non-secure-only. Commands targeting a programming interface other than Non-secure do not reach the accelerated backend or Non-secure notifiers, while Non-secure stage-1 CMD_TLBI_NH_ALL remains forwarded to the host. Include the command queue SEC_SID and target SEC_SID in the relevant invalidation tracepoints. Signed-off-by: Tao Tang Tested-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 100 ++++++++++++++++++++++++++++- hw/arm/smmuv3-accel-stubs.c | 6 +- hw/arm/smmuv3-accel.c | 30 +++++++-- hw/arm/smmuv3-accel.h | 6 +- hw/arm/smmuv3.c | 121 ++++++++++++++++++++++++++--------- hw/arm/trace-events | 12 ++-- include/hw/arm/smmu-common.h | 6 ++ 7 files changed, 231 insertions(+), 50 deletions(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 3d4b6b3a287..e8a1ed65c19 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -217,12 +217,30 @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *c= fg, SMMUTLBEntry *new, g_hash_table_insert(bs->iotlb, key, new); } =20 +static gboolean smmu_hash_remove_by_sec_sid(gpointer key, gpointer value, + gpointer user_data) +{ + SMMUIOTLBKey *iotlb_key =3D (SMMUIOTLBKey *)key; + SMMUSecSID *sec_sid =3D (SMMUSecSID *)user_data; + + return SMMU_IOTLB_SEC_SID(*iotlb_key) =3D=3D *sec_sid; +} + void smmu_iotlb_inv_all(SMMUState *s) { trace_smmu_iotlb_inv_all(); g_hash_table_remove_all(s->iotlb); } =20 +void smmu_iotlb_inv_by_sec_sid(SMMUState *s, SMMUSecSID sec_sid) +{ + g_assert(sec_sid < SMMU_SEC_SID_NUM); + + trace_smmu_iotlb_inv_by_sec_sid(sec_sid); + g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_sec_sid, + &sec_sid); +} + static gboolean smmu_hash_remove_by_asid_vmid(gpointer key, gpointer value, gpointer user_data) { @@ -298,6 +316,16 @@ static gboolean smmu_hash_remove_by_vmid_ipa(gpointer = key, gpointer value, ((entry->iova & ~info->mask) =3D=3D info->iova); } =20 +typedef struct SMMUConfigInvRangeInfo { + SMMUSIDRange sid_range; + SMMUSecSID sec_sid; +} SMMUConfigInvRangeInfo; + +typedef struct SMMUConfigInvSdevInfo { + SMMUDevice *sdev; + SMMUSecSID sec_sid; +} SMMUConfigInvSdevInfo; + static gboolean smmu_hash_remove_by_sid_range(gpointer key, gpointer value, gpointer user_= data) { @@ -309,7 +337,26 @@ smmu_hash_remove_by_sid_range(gpointer key, gpointer v= alue, gpointer user_data) if (sid < sid_range->start || sid > sid_range->end) { return false; } - trace_smmu_config_cache_inv(sid); + trace_smmu_config_cache_inv(config_key->sec_sid, sid); + return true; +} + +static gboolean +smmu_hash_remove_by_sid_range_sec(gpointer key, gpointer value, + gpointer user_data) +{ + SMMUConfigKey *config_key =3D (SMMUConfigKey *)key; + SMMUConfigInvRangeInfo *info =3D (SMMUConfigInvRangeInfo *)user_data; + SMMUDevice *sdev =3D config_key->sdev; + uint32_t sid =3D smmu_get_sid(sdev); + + if (config_key->sec_sid !=3D info->sec_sid) { + return false; + } + if (sid < info->sid_range.start || sid > info->sid_range.end) { + return false; + } + trace_smmu_config_cache_inv(config_key->sec_sid, sid); return true; } =20 @@ -320,6 +367,23 @@ void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDR= ange sid_range) &sid_range); } =20 +void smmu_configs_inv_sid_range_by_sec_sid(SMMUState *s, + SMMUSIDRange sid_range, + SMMUSecSID sec_sid) +{ + SMMUConfigInvRangeInfo info =3D { + .sid_range =3D sid_range, + .sec_sid =3D sec_sid, + }; + + g_assert(sec_sid < SMMU_SEC_SID_NUM); + + trace_smmu_configs_inv_sid_range_by_sec_sid(sec_sid, sid_range.start, + sid_range.end); + g_hash_table_foreach_remove(s->configs, smmu_hash_remove_by_sid_range_= sec, + &info); +} + static gboolean smmu_hash_remove_by_sdev(gpointer key, gpointer value, gpointer user_data) { @@ -329,7 +393,25 @@ static gboolean smmu_hash_remove_by_sdev(gpointer key,= gpointer value, if (config_key->sdev !=3D target) { return false; } - trace_smmu_config_cache_inv(smmu_get_sid(target)); + trace_smmu_config_cache_inv(config_key->sec_sid, + smmu_get_sid(target)); + return true; +} + +static gboolean smmu_hash_remove_by_sdev_sec(gpointer key, gpointer value, + gpointer user_data) +{ + SMMUConfigKey *config_key =3D (SMMUConfigKey *)key; + SMMUConfigInvSdevInfo *info =3D (SMMUConfigInvSdevInfo *)user_data; + + if (config_key->sdev !=3D info->sdev) { + return false; + } + if (config_key->sec_sid !=3D info->sec_sid) { + return false; + } + trace_smmu_config_cache_inv(config_key->sec_sid, + smmu_get_sid(info->sdev)); return true; } =20 @@ -338,6 +420,20 @@ void smmu_configs_inv_sdev(SMMUState *s, SMMUDevice *s= dev) g_hash_table_foreach_remove(s->configs, smmu_hash_remove_by_sdev, sdev= ); } =20 +void smmu_configs_inv_sdev_by_sec_sid(SMMUState *s, SMMUDevice *sdev, + SMMUSecSID sec_sid) +{ + SMMUConfigInvSdevInfo info =3D { + .sdev =3D sdev, + .sec_sid =3D sec_sid, + }; + + g_assert(sec_sid < SMMU_SEC_SID_NUM); + + g_hash_table_foreach_remove(s->configs, smmu_hash_remove_by_sdev_sec, + &info); +} + 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, SMMUSecSID sec_sid) diff --git a/hw/arm/smmuv3-accel-stubs.c b/hw/arm/smmuv3-accel-stubs.c index b8dd7e7b897..ecc6890a9cc 100644 --- a/hw/arm/smmuv3-accel-stubs.c +++ b/hw/arm/smmuv3-accel-stubs.c @@ -16,13 +16,13 @@ bool smmuv3_accel_init(SMMUv3State *s, Error **errp) } =20 bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid, - Error **errp) + SMMUSecSID sec_sid, Error **errp) { return true; } =20 bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range, - Error **errp) + SMMUSecSID sec_sid, Error **errp) { return true; } @@ -33,7 +33,7 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error = **errp) } =20 bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sde= v, - Error **errp) + SMMUSecSID sec_sid, Error **errp) { return true; } diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 9d207acc8e3..a738c4fad67 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -283,7 +283,7 @@ smmuv3_accel_dev_alloc_translate(SMMUv3AccelDevice *acc= el_dev, STE *ste, } =20 bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid, - Error **errp) + SMMUSecSID sec_sid, Error **errp) { SMMUEventInfo event =3D {.type =3D SMMU_EVT_NONE, .sid =3D sid, .inval_ste_allowed =3D true}; @@ -294,7 +294,13 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevi= ce *sdev, int sid, SMMUS1Hwpt *s1_hwpt =3D NULL; const char *type; STE ste; - SMMUSecSID sec_sid =3D SMMU_SEC_SID_NS; + + g_assert(sec_sid < SMMU_SEC_SID_NUM); + + /* Acceleration supports only the Non-secure programming interface. */ + if (sec_sid !=3D SMMU_SEC_SID_NS) { + return true; + } =20 if (!accel || !accel->viommu) { return true; @@ -377,13 +383,20 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDev= ice *sdev, int sid, } =20 bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range, - Error **errp) + SMMUSecSID sec_sid, Error **errp) { SMMUv3AccelState *accel =3D s->s_accel; SMMUv3AccelDevice *accel_dev; Error *local_err =3D NULL; bool all_ok =3D true; =20 + g_assert(sec_sid < SMMU_SEC_SID_NUM); + + /* Acceleration supports only the Non-secure programming interface. */ + if (sec_sid !=3D SMMU_SEC_SID_NS) { + return true; + } + if (!accel || !accel->viommu) { return true; } @@ -393,7 +406,7 @@ bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMM= USIDRange *range, =20 if (sid >=3D range->start && sid <=3D range->end) { if (!smmuv3_accel_install_ste(s, &accel_dev->sdev, - sid, &local_err)) { + sid, sec_sid, &local_err)) { error_append_hint(&local_err, "Device 0x%x: Failed to inst= all " "STE\n", sid); error_report_err(local_err); @@ -416,12 +429,19 @@ bool smmuv3_accel_install_ste_range(SMMUv3State *s, S= MMUSIDRange *range, * non SID invalidations such as SMMU_CMD_TLBI_NH_ASID and SMMU_CMD_TLBI_N= H_VA. */ bool smmuv3_accel_issue_inv_cmd(SMMUv3State *bs, void *cmd, SMMUDevice *sd= ev, - Error **errp) + SMMUSecSID sec_sid, Error **errp) { SMMUv3State *s =3D ARM_SMMUV3(bs); SMMUv3AccelState *accel =3D s->s_accel; uint32_t entry_num =3D 1; =20 + g_assert(sec_sid < SMMU_SEC_SID_NUM); + + /* Acceleration supports only the Non-secure programming interface. */ + if (sec_sid !=3D SMMU_SEC_SID_NS) { + return true; + } + /* * No accel or viommu means no VFIO/IOMMUFD devices, nothing to * invalidate. diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h index ea11d513cc9..761943f137a 100644 --- a/hw/arm/smmuv3-accel.h +++ b/hw/arm/smmuv3-accel.h @@ -89,12 +89,12 @@ typedef struct SMMUv3AccelDevice { =20 bool smmuv3_accel_init(SMMUv3State *s, Error **errp); bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid, - Error **errp); + SMMUSecSID sec_sid, Error **errp); bool smmuv3_accel_install_ste_range(SMMUv3State *s, SMMUSIDRange *range, - Error **errp); + SMMUSecSID sec_sid, Error **errp); bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp); bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sde= v, - Error **errp); + SMMUSecSID sec_sid, Error **errp); void smmuv3_accel_idr_override(SMMUv3State *s); bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp); int smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t typ= e, diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 7e08b88689f..47f0d575817 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1005,12 +1005,13 @@ static SMMUTransCfg *smmuv3_get_config(SMMUDevice *= sdev, SMMUEventInfo *event, return cfg; } =20 -static void smmuv3_flush_config(SMMUDevice *sdev) +static void smmuv3_flush_config_by_sec_sid(SMMUDevice *sdev, + SMMUSecSID sec_sid) { SMMUv3State *s =3D sdev->smmu; SMMUState *bc =3D &s->smmu_state; =20 - smmu_configs_inv_sdev(bc, sdev); + smmu_configs_inv_sdev_by_sec_sid(bc, sdev, sec_sid); } =20 /* Do translation with TLB lookup. */ @@ -1314,10 +1315,16 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *m= r, /* 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 + /* IOMMU notifiers are supported only for Non-secure devices. */ + if (sec_sid !=3D SMMU_SEC_SID_NS) { + return; + } + QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) { IOMMUMemoryRegion *mr =3D &sdev->iommu; IOMMUNotifier *n; @@ -1331,8 +1338,16 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, = int asid, int vmid, } } =20 +static void smmuv3_inv_notifiers_all(SMMUState *s, SMMUSecSID sec_sid) +{ + /* IOMMU notifiers are supported only for Non-secure devices. */ + if (sec_sid =3D=3D SMMU_SEC_SID_NS) { + smmu_inv_notifiers_all(s); + } +} + static void smmuv3_range_inval(SMMUState *s, Cmd *cmd, SMMUStage stage, - SMMUSecSID sec_sid) + SMMUSecSID sec_sid, bool use_vmid) { dma_addr_t end, addr =3D CMD_ADDR(cmd); uint8_t type =3D CMD_TYPE(cmd); @@ -1345,10 +1360,8 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cm= d, SMMUStage stage, uint64_t num_pages; uint8_t granule; int asid =3D -1; - SMMUv3State *smmuv3 =3D ARM_SMMUV3(s); =20 - /* Only consider VMID if stage-2 is supported. */ - if (STAGE2_SUPPORTED(smmuv3)) { + if (use_vmid) { vmid =3D CMD_VMID(cmd); } =20 @@ -1359,7 +1372,8 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd= , SMMUStage stage, if (!tg) { 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); + smmuv3_inv_notifiers_iova(s, asid, vmid, addr, tg, 1, stage, + sec_sid); if (stage =3D=3D SMMU_STAGE_1) { smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, 1, ttl, sec_sid); } else { @@ -1383,7 +1397,7 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd= , SMMUStage stage, 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); + num_pages, stage, sec_sid); if (stage =3D=3D SMMU_STAGE_1) { smmu_iotlb_inv_iova(s, asid, vmid, addr, tg, num_pages, ttl, sec_sid); @@ -1394,6 +1408,26 @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cm= d, SMMUStage stage, } } =20 +static inline bool +smmu_cmdq_stage2_supported(SMMUv3State *s, SMMUSecSID sec_sid) +{ + /* IDR0.S2P: Stage 2 translation supported */ + bool s2p =3D STAGE2_SUPPORTED(s); + if (!s2p) { + return false; + } + + /* + * For Secure Command queue, Secure stage 2 is additionally gated by S= EL2 + * (SEL2 is 0 if S2P is 0). + */ + if (sec_sid =3D=3D SMMU_SEC_SID_S) { + return FIELD_EX32(s->bank[SMMU_SEC_SID_S].idr[1], S_IDR1, SEL2); + } + + return true; +} + static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp, SMMUSecSID se= c_sid) { SMMUState *bs =3D ARM_SMMU(s); @@ -1403,6 +1437,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp, SMMUSecSID sec_sid) SMMUCommandType type =3D 0; MemTxAttrs attrs =3D smmu_get_txattrs(sec_sid); AddressSpace *as =3D smmu_get_address_space(bs, sec_sid); + bool queue_stage2_supported =3D smmu_cmdq_stage2_supported(s, sec_sid); =20 if (!smmuv3_cmdq_enabled(s, sec_sid)) { return 0; @@ -1464,12 +1499,12 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Erro= r **errp, SMMUSecSID sec_sid) break; } =20 - trace_smmuv3_cmdq_cfgi_ste(sid); - if (!smmuv3_accel_install_ste(s, sdev, sid, errp)) { + trace_smmuv3_cmdq_cfgi_ste(sec_sid, ssec, sid); + if (!smmuv3_accel_install_ste(s, sdev, sid, ssec, errp)) { cmd_error =3D SMMU_CERROR_ILL; break; } - smmuv3_flush_config(sdev); + smmuv3_flush_config_by_sec_sid(sdev, ssec); =20 break; } @@ -1483,12 +1518,13 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Erro= r **errp, SMMUSecSID sec_sid) sid_range.start =3D sid & ~mask; sid_range.end =3D sid_range.start + mask; =20 - trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.en= d); - if (!smmuv3_accel_install_ste_range(s, &sid_range, errp)) { + trace_smmuv3_cmdq_cfgi_ste_range(sec_sid, ssec, + sid_range.start, sid_range.en= d); + if (!smmuv3_accel_install_ste_range(s, &sid_range, ssec, errp)= ) { cmd_error =3D SMMU_CERROR_ILL; break; } - smmu_configs_inv_sid_range(bs, sid_range); + smmu_configs_inv_sid_range_by_sec_sid(bs, sid_range, ssec); break; } case SMMU_CMD_CFGI_CD: @@ -1510,9 +1546,9 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp, SMMUSecSID sec_sid) break; } =20 - trace_smmuv3_cmdq_cfgi_cd(sid); - smmuv3_flush_config(sdev); - if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, errp)) { + trace_smmuv3_cmdq_cfgi_cd(sec_sid, ssec, sid); + smmuv3_flush_config_by_sec_sid(sdev, ssec); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, ssec, errp)) { cmd_error =3D SMMU_CERROR_ILL; break; } @@ -1532,14 +1568,14 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Erro= r **errp, SMMUSecSID sec_sid) * VMID is only matched when stage 2 is supported, otherwise s= et it * to -1 as the value used for stage-1 only VMIDs. */ - if (STAGE2_SUPPORTED(s)) { + if (queue_stage2_supported) { vmid =3D CMD_VMID(&cmd); } =20 trace_smmuv3_cmdq_tlbi_nh_asid(sec_sid, asid); - smmu_inv_notifiers_all(&s->smmu_state); + smmuv3_inv_notifiers_all(bs, sec_sid); smmu_iotlb_inv_asid_vmid(bs, asid, vmid, sec_sid); - if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, sec_sid, errp))= { cmd_error =3D SMMU_CERROR_ILL; break; } @@ -1558,31 +1594,51 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Erro= r **errp, SMMUSecSID sec_sid) * If stage-2 is supported, invalidate for this VMID only, oth= erwise * invalidate the whole thing. */ - if (STAGE2_SUPPORTED(s)) { + if (queue_stage2_supported) { vmid =3D CMD_VMID(&cmd); trace_smmuv3_cmdq_tlbi_nh(sec_sid, vmid); smmu_iotlb_inv_vmid_s1(bs, vmid, sec_sid); break; } - QEMU_FALLTHROUGH; + trace_smmuv3_cmdq_tlbi_nh(sec_sid, vmid); + smmuv3_inv_notifiers_all(bs, sec_sid); + smmu_iotlb_inv_by_sec_sid(bs, sec_sid); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, sec_sid, errp))= { + cmd_error =3D SMMU_CERROR_ILL; + break; + } + break; } case SMMU_CMD_TLBI_NSNH_ALL: - trace_smmuv3_cmdq_tlbi_nsnh(); - smmu_inv_notifiers_all(&s->smmu_state); - smmu_iotlb_inv_all(bs); - if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { + { + /* + * CMD_TLBI_NSNH_ALL targets Non-secure entries when issued fr= om the + * Non-secure or Secure Command queue, but Realm entries when = issued + * from the Realm Command queue. + * (IHI 0070G.b) 4.4.4.1 CMD_TLBI_NSNH_ALL, Page 194 + */ + SMMUSecSID target_sec_sid =3D sec_sid > SMMU_SEC_SID_S ? + sec_sid : SMMU_SEC_SID_NS; + + trace_smmuv3_cmdq_tlbi_nsnh(sec_sid, target_sec_sid); + smmuv3_inv_notifiers_all(bs, target_sec_sid); + smmu_iotlb_inv_by_sec_sid(bs, target_sec_sid); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, target_sec_sid, + errp)) { cmd_error =3D SMMU_CERROR_ILL; break; } break; + } case SMMU_CMD_TLBI_NH_VAA: case SMMU_CMD_TLBI_NH_VA: if (!STAGE1_SUPPORTED(s)) { cmd_error =3D SMMU_CERROR_ILL; break; } - smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1, SMMU_SEC_SID_NS); - if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, errp)) { + smmuv3_range_inval(bs, &cmd, SMMU_STAGE_1, sec_sid, + queue_stage2_supported); + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, NULL, sec_sid, errp))= { cmd_error =3D SMMU_CERROR_ILL; break; } @@ -1597,7 +1653,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp, SMMUSecSID sec_sid) } =20 trace_smmuv3_cmdq_tlbi_s12_vmid(vmid); - smmu_inv_notifiers_all(&s->smmu_state); + smmuv3_inv_notifiers_all(bs, SMMU_SEC_SID_NS); smmu_iotlb_inv_vmid(bs, vmid, SMMU_SEC_SID_NS); break; } @@ -1610,7 +1666,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp, SMMUSecSID sec_sid) * 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, SMMU_SEC_SID_NS, tr= ue); break; case SMMU_CMD_ATC_INV: { @@ -1621,7 +1677,8 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp, SMMUSecSID sec_sid) break; } =20 - if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, errp)) { + if (!smmuv3_accel_issue_inv_cmd(s, &cmd, sdev, + SMMU_SEC_SID_NS, errp)) { cmd_error =3D SMMU_CERROR_ILL; break; } diff --git a/hw/arm/trace-events b/hw/arm/trace-events index ccc0ab50164..7cd4eb38578 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -19,12 +19,14 @@ smmu_ptw_page_pte(int stage, int level, uint64_t iova,= uint64_t baseaddr, uint6 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_iotlb_inv_all(void) "IOTLB invalidate all" +smmu_iotlb_inv_by_sec_sid(int sec_sid) "IOTLB invalidate sec_sid=3D%d" smmu_iotlb_inv_asid_vmid(int sec_sid, int asid, int vmid) "IOTLB invalidat= e sec_sid=3D%d asid=3D%d vmid=3D%d" smmu_iotlb_inv_vmid(int sec_sid, int vmid) "IOTLB invalidate sec_sid=3D%d = vmid=3D%d" smmu_iotlb_inv_vmid_s1(int sec_sid, int vmid) "IOTLB invalidate S1 sec_sid= =3D%d vmid=3D%d" smmu_iotlb_inv_iova(int sec_sid, int asid, uint64_t addr) "IOTLB invalidat= e sec_sid=3D%d asid=3D%d addr=3D0x%"PRIx64 smmu_configs_inv_sid_range(uint32_t start, uint32_t end) "Config cache INV= SID range from 0x%x to 0x%x" -smmu_config_cache_inv(uint32_t sid) "Config cache INV for sid=3D0x%x" +smmu_configs_inv_sid_range_by_sec_sid(int sec_sid, uint32_t start, uint32_= t end) "Config cache INV sec_sid=3D%d SID range from 0x%x to 0x%x" +smmu_config_cache_inv(int sec_sid, uint32_t sid) "Config cache INV sec_sid= =3D%d sid=3D0x%x" smmu_inv_notifiers_mr(const char *name) "iommu mr=3D%s" smmu_iotlb_lookup_hit(int sec_sid, int asid, int vmid, uint64_t addr, uint= 32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT sec_sid=3D%d asid=3D%= d vmid=3D%d addr=3D0x%"PRIx64" hit=3D%d miss=3D%d hit rate=3D%d" smmu_iotlb_lookup_miss(int sec_sid, int asid, int vmid, uint64_t addr, uin= t32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS sec_sid=3D%d asid= =3D%d vmid=3D%d addr=3D0x%"PRIx64" hit=3D%d miss=3D%d hit rate=3D%d" @@ -52,14 +54,14 @@ smmuv3_translate_success(const char *n, uint16_t sid, u= int64_t iova, uint64_t tr smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64 smmuv3_decode_cd(uint32_t oas) "oas=3D%d" smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz= , bool had) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d had:%d" -smmuv3_cmdq_cfgi_ste(int streamid) "streamid=3D 0x%x" -smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=3D0x%x - end=3D0x%x" -smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=3D0x%x" +smmuv3_cmdq_cfgi_ste(int sec_sid, int ssec, int streamid) "cmdq_sec_sid=3D= %d ssec=3D%d streamid=3D0x%x" +smmuv3_cmdq_cfgi_ste_range(int sec_sid, int ssec, int start, int end) "cmd= q_sec_sid=3D%d ssec=3D%d start=3D0x%x - end=3D0x%x" +smmuv3_cmdq_cfgi_cd(int sec_sid, int ssec, uint32_t sid) "cmdq_sec_sid=3D%= d ssec=3D%d 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 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 sec_sid, int vmid) "sec_sid=3D%d vmid=3D%d" -smmuv3_cmdq_tlbi_nsnh(void) "" +smmuv3_cmdq_tlbi_nsnh(int sec_sid, int target_sec_sid) "cmdq_sec_sid=3D%d = target_sec_sid=3D%d" smmuv3_cmdq_tlbi_nh_asid(int sec_sid, int asid) "sec_sid=3D%d asid=3D%d" 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" diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index 8e971c28093..a21c6061808 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -269,6 +269,7 @@ SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uin= t64_t iova, 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_by_sec_sid(SMMUState *s, SMMUSecSID sec_sid); void smmu_iotlb_inv_asid_vmid(SMMUState *s, int asid, int vmid, SMMUSecSID sec_sid); void smmu_iotlb_inv_vmid(SMMUState *s, int vmid, SMMUSecSID sec_sid); @@ -280,7 +281,12 @@ void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_ad= dr_t ipa, uint8_t tg, 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_sid_range_by_sec_sid(SMMUState *s, + SMMUSIDRange sid_range, + SMMUSecSID sec_sid); void smmu_configs_inv_sdev(SMMUState *s, SMMUDevice *sdev); +void smmu_configs_inv_sdev_by_sec_sid(SMMUState *s, SMMUDevice *sdev, + SMMUSecSID sec_sid); /* 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 Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638527508316.2387938734008; Thu, 13 Aug 2026 09:28:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGA-0003VB-I8; Thu, 13 Aug 2026 12:26:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYFu-0003G8-NJ; Thu, 13 Aug 2026 12:26:10 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFq-0001B4-O6; Thu, 13 Aug 2026 12:26:08 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwBXWnYb8H1qBSNvAw--.34321S2; Fri, 14 Aug 2026 00:26:03 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8Dw4XUX8H1q5iwjAA--.55915S3; Fri, 14 Aug 2026 00:25:59 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 16/28] hw/arm/smmuv3: Add access checks for GERROR_IRQ_CFG registers Date: Fri, 14 Aug 2026 00:25:54 +0800 Message-Id: <20260813162558.2808607-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8Dw4XUX8H1q5iwjAA--.55915S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HpgAAsx Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3WF1rAFWkAF4UtryrZr4DCFg_yoWxJrW8pr yxK3sIgr4Uta1IqFZaka1Yyw1ru3s7tF15tryakFnxJw1UCrWYyw40gFWSqwnrWFykWws7 ta13Kr48urn8Ar7anT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638529072158501 Content-Type: text/plain; charset="utf-8" Add helpers that separate IRQ_CFG register presence from the runtime IRQ enable guard. The Non-secure and Secure GERROR_IRQ_CFG register sets both use SMMU_IDR0.MSI for presence, while writability additionally requires GERROR_IRQEN to be clear. IRQ_CTRL and IRQ_CTRLACK share one synchronous backing field in the current model. Reads return RES0 when the register set is absent. Writes are ignored when it is absent or GERROR_IRQEN is set. Apply the same checks to all three GERROR_IRQ_CFG registers and mask reserved bits in CFG0 and CFG2. Fixes: fae4be38b35d ("hw/arm/smmuv3: Implement MMIO write operations") Fixes: 10a83cb9887e ("hw/arm/smmuv3: Skeleton") Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 47f0d575817..628911d3f21 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1428,6 +1428,62 @@ smmu_cmdq_stage2_supported(SMMUv3State *s, SMMUSecSI= D sec_sid) return true; } =20 +/* Check whether the selected IRQ_CFG register set is present. */ +static bool smmu_irq_cfg_present(SMMUv3State *s, SMMUSecSID sec_sid, + SMMUIrq irq) +{ + SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + + switch (irq) { + case SMMU_IRQ_GERROR: + switch (sec_sid) { + case SMMU_SEC_SID_NS: + case SMMU_SEC_SID_S: + return FIELD_EX32(bank->idr[0], IDR0, MSI); + case SMMU_SEC_SID_NUM: + g_assert_not_reached(); + } + break; + case SMMU_IRQ_EVTQ: + case SMMU_IRQ_PRIQ: + case SMMU_IRQ_CMD_SYNC: + g_assert_not_reached(); + } + + g_assert_not_reached(); +} + +/* Check whether the selected IRQ_CFG register set is writable. */ +static bool smmu_irq_cfg_writable(SMMUv3State *s, SMMUSecSID sec_sid, + SMMUIrq irq) +{ + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + uint32_t irqen; + + if (!smmu_irq_cfg_present(s, sec_sid, irq)) { + return false; + } + + switch (irq) { + case SMMU_IRQ_GERROR: + irqen =3D FIELD_EX32(bank->irq_ctrl, IRQ_CTRL, GERROR_IRQEN); + break; + case SMMU_IRQ_EVTQ: + case SMMU_IRQ_PRIQ: + case SMMU_IRQ_CMD_SYNC: + g_assert_not_reached(); + } + + /* IRQ_CTRL and IRQ_CTRLACK share one synchronous backing field. */ + return irqen =3D=3D 0; +} + +static bool +smmu_gerror_irq_cfg_writable(SMMUv3State *s, SMMUSecSID sec_sid) +{ + return smmu_irq_cfg_writable(s, sec_sid, SMMU_IRQ_GERROR); +} + static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp, SMMUSecSID se= c_sid) { SMMUState *bs =3D ARM_SMMU(s); @@ -1735,7 +1791,14 @@ static MemTxResult smmu_writell(SMMUv3State *s, hwad= dr 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; @@ -1803,16 +1866,42 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, smmuv3_cmdq_consume(s, &local_err, reg_sec_sid); break; 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); break; 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; + } + + data &=3D SMMU_GERROR_IRQ_CFG0_RESERVED >> 32; bank->gerror_irq_cfg0 =3D deposit64(bank->gerror_irq_cfg0, 32, 32,= data); break; 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; break; case A_GERROR_IRQ_CFG2: - bank->gerror_irq_cfg2 =3D data; + if (!smmu_gerror_irq_cfg_writable(s, reg_sec_sid)) { + qemu_log_mask(LOG_GUEST_ERROR, "GERROR_IRQ_CFG2 write ignored:= " + "register is RO when IRQ enabled\n"); + return MEMTX_OK; + } + + bank->gerror_irq_cfg2 =3D data & SMMU_GERROR_IRQ_CFG2_RESERVED; break; case A_GBPA: /* @@ -1938,6 +2027,11 @@ static MemTxResult smmu_readll(SMMUv3State *s, hwadd= r offset, =20 switch (offset) { case A_GERROR_IRQ_CFG0: + if (!smmu_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_GERROR)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + *data =3D bank->gerror_irq_cfg0; return MEMTX_OK; case A_STRTAB_BASE: @@ -2006,15 +2100,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_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_GERROR)) { + *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_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_GERROR)) { + *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_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_GERROR)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + *data =3D bank->gerror_irq_cfg1; return MEMTX_OK; case A_GERROR_IRQ_CFG2: + if (!smmu_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_GERROR)) { + *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 Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638379875140.78314965441723; Thu, 13 Aug 2026 09:26:19 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFw-0003Hn-P8; Thu, 13 Aug 2026 12:26:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYFq-0003EK-KK; Thu, 13 Aug 2026 12:26:08 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFo-0001AK-QL; Thu, 13 Aug 2026 12:26:06 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwBHJpEa8H1q8CJvAw--.34313S2; Fri, 14 Aug 2026 00:26:02 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8Dw4XUX8H1q5iwjAA--.55915S4; Fri, 14 Aug 2026 00:26:00 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 17/28] hw/arm/smmuv3: Add access checks for STRTAB_BASE and CR2 registers Date: Fri, 14 Aug 2026 00:25:55 +0800 Message-Id: <20260813162558.2808607-2-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8Dw4XUX8H1q5iwjAA--.55915S4 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HpgABsw Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxZFW8JrWfZr1kGrW3GFyDKFg_yoWrtr1rpr Z7G34agr47tayI9asxJa1Yyws8CayvgF1UJry7GF97uw1UJrW5XF4rWrWfX3WkXFy8Jws7 Gr4akay3urW8tFJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638380483158500 Content-Type: text/plain; charset="utf-8" Add access control for SMMU_STRTAB_BASE and SMMU_CR2 registers to ensure they can only be modified when the SMMU is disabled. This implements: - smmuv3_smmu_disabled_stable(): Check whether the SMMU is in a stable disabled state (CR0.SMMUEN =3D=3D 0 and CR0ACK.SMMUEN =3D=3D 0); - smmu_strtab_base_writable(): returns true only when IDR1.TABLES_PRESET=3D= =3D0 and SMMU is completely disabled. Additionally, mask reserved bits on writes to SMMU_STRTAB_BASE using SMMU_STRTAB_BASE_RESERVED. Fixes: fae4be38b35d ("hw/arm/smmuv3: Implement MMIO write operations") Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 628911d3f21..de8ca7cda48 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1484,6 +1484,36 @@ smmu_gerror_irq_cfg_writable(SMMUv3State *s, SMMUSec= SID sec_sid) return smmu_irq_cfg_writable(s, sec_sid, SMMU_IRQ_GERROR); } =20 +static inline int smmuv3_get_cr0ack_smmuen(SMMUv3State *s, SMMUSecSID sec_= sid) +{ + /* + * CR0, CR0ACK, S_CR0 and S_CR0ACK are bit-layout compatible, so we re= use + * the CR0 field definitions and only switch banks via sec_sid to redu= ce + * code duplication. Also the other bits in CR0/CR0ACK are relevant he= re. + */ + return FIELD_EX32(s->bank[sec_sid].cr0ack, CR0, SMMUEN); +} + +/* Check if SMMU is disabled in stable status */ +static inline bool smmuv3_smmu_disabled_stable(SMMUv3State *s, SMMUSecSID = sec_sid) +{ + 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) +{ + /* SMMU_IDR1.TABLES_PRESET applies to both modeled interfaces. */ + if (FIELD_EX32(s->bank[SMMU_SEC_SID_NS].idr[1], IDR1, TABLES_PRESET)) { + return false; + } + + /* Check SMMUEN conditions for the specific security domain */ + return smmuv3_smmu_disabled_stable(s, sec_sid); +} + static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp, SMMUSecSID se= c_sid) { SMMUState *bs =3D ARM_SMMU(s); @@ -1801,7 +1831,14 @@ static MemTxResult smmu_writell(SMMUv3State *s, hwad= dr offset, 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; @@ -1852,7 +1889,15 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, bank->cr[1] =3D data; break; case A_CR2: - bank->cr[2] =3D data; + if (smmuv3_smmu_disabled_stable(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"); + } break; case A_IRQ_CTRL: bank->irq_ctrl =3D data; @@ -1915,12 +1960,32 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, } break; 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); break; 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); break; 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); --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638597809326.47932981089787; Thu, 13 Aug 2026 09:29:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGL-0003pI-8G; Thu, 13 Aug 2026 12:26:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYFw-0003Lr-VG; Thu, 13 Aug 2026 12:26:14 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFs-0001Bx-TM; Thu, 13 Aug 2026 12:26:12 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwD3_hoe8H1qKSNvAw--.33937S2; Fri, 14 Aug 2026 00:26:06 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8Dw4XUX8H1q5iwjAA--.55915S5; Fri, 14 Aug 2026 00:26:01 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 18/28] hw/arm/smmuv3: Add access checks for CMDQ and EVENTQ registers Date: Fri, 14 Aug 2026 00:25:56 +0800 Message-Id: <20260813162558.2808607-3-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8Dw4XUX8H1q5iwjAA--.55915S5 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HqAAAs- Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3uryrGFykXr1fCryxKFy5XFb_yoWktr43pr 97GFy3Kr4a9w4Sqa93Ga1Yya1Uua1xtr9rKr98WFn5Ww1UGrW5Za18WFWfXas3JF18Xws7 GwsIkFW3urW7G3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638599674158501 Content-Type: text/plain; charset="utf-8" Add access control for command queue and event queue related registers to ensure they can only be modified under proper conditions. For command queue (CMDQ): - smmu_cmdq_disabled_stable(): checks CMDQ bit in CR0/CR0ACK - smmu_cmdq_base_writable(): checks IDR1.QUEUES_PRESET=3D=3D0 and CMDQ disa= bled For event queue (EVTQ): - smmu_eventq_disabled_stable(): checks EVTQ bit in CR0/CR0ACK - smmu_eventq_base_writable(): checks IDR1.QUEUES_PRESET=3D=3D0 and EVTQ di= sabled - smmu_irq_cfg_present(): checks SMMU_IDR0.MSI for the Non-secure EVENTQ_IRQ_CFG register set and SMMU_S_IDR0.MSI for the Secure set - smmu_eventq_irq_cfg_writable(): additionally checks EVENTQ_IRQEN Absent EVENTQ_IRQ_CFG registers read as RES0. Present registers retain their programmed values for readback. The helper remains keyed by SEC_SID so future Realm support can select SMMU_R_IDR0.MSI. Additionally, mask reserved bits on writes using SMMU_QUEUE_BASE_RESERVED for queue base registers and SMMU_EVENTQ_IRQ_CFG0_RESERVED for EVENTQ_IRQ_CFG0. Fixes: fae4be38b35d ("hw/arm/smmuv3: Implement MMIO write operations") Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 204 insertions(+), 6 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index de8ca7cda48..efa78869251 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1432,19 +1432,29 @@ smmu_cmdq_stage2_supported(SMMUv3State *s, SMMUSecS= ID sec_sid) static bool smmu_irq_cfg_present(SMMUv3State *s, SMMUSecSID sec_sid, SMMUIrq irq) { - SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); + SMMUv3RegBank *ns_bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); =20 switch (irq) { case SMMU_IRQ_GERROR: switch (sec_sid) { case SMMU_SEC_SID_NS: case SMMU_SEC_SID_S: - return FIELD_EX32(bank->idr[0], IDR0, MSI); + return FIELD_EX32(ns_bank->idr[0], IDR0, MSI); case SMMU_SEC_SID_NUM: g_assert_not_reached(); } break; case SMMU_IRQ_EVTQ: + switch (sec_sid) { + case SMMU_SEC_SID_NS: + return FIELD_EX32(bank->idr[0], IDR0, MSI); + case SMMU_SEC_SID_S: + return FIELD_EX32(bank->idr[0], S_IDR0, MSI); + case SMMU_SEC_SID_NUM: + g_assert_not_reached(); + } + break; case SMMU_IRQ_PRIQ: case SMMU_IRQ_CMD_SYNC: g_assert_not_reached(); @@ -1469,6 +1479,8 @@ static bool smmu_irq_cfg_writable(SMMUv3State *s, SMM= USecSID sec_sid, irqen =3D FIELD_EX32(bank->irq_ctrl, IRQ_CTRL, GERROR_IRQEN); break; case SMMU_IRQ_EVTQ: + irqen =3D FIELD_EX32(bank->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN); + break; case SMMU_IRQ_PRIQ: case SMMU_IRQ_CMD_SYNC: g_assert_not_reached(); @@ -1514,6 +1526,69 @@ static bool smmu_strtab_base_writable(SMMUv3State *s= , SMMUSecSID sec_sid) return smmuv3_smmu_disabled_stable(s, sec_sid); } =20 +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 CMDQ is disabled in stable status */ +static bool smmu_cmdq_disabled_stable(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) +{ + /* SMMU_IDR1.QUEUES_PRESET applies to both modeled interfaces. */ + if (FIELD_EX32(s->bank[SMMU_SEC_SID_NS].idr[1], IDR1, QUEUES_PRESET)) { + return false; + } + + return smmu_cmdq_disabled_stable(s, sec_sid); +} + +/* Check if EVENTQ is disabled in stable status */ +static bool smmu_eventq_disabled_stable(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); +} + +/* Check if EVENTQ_BASE register is writable */ +static bool smmu_eventq_base_writable(SMMUv3State *s, SMMUSecSID sec_sid) +{ + if (FIELD_EX32(s->bank[SMMU_SEC_SID_NS].idr[1], IDR1, QUEUES_PRESET)) { + return false; + } + + return smmu_eventq_disabled_stable(s, sec_sid); +} + +/* Check if EVENTQ_IRQ_CFGx is writable */ +static bool smmu_eventq_irq_cfg_writable(SMMUv3State *s, SMMUSecSID sec_si= d) +{ + return smmu_irq_cfg_writable(s, sec_sid, SMMU_IRQ_EVTQ); +} + static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp, SMMUSecSID se= c_sid) { SMMUState *bs =3D ARM_SMMU(s); @@ -1841,21 +1916,39 @@ static MemTxResult smmu_writell(SMMUv3State *s, hwa= ddr offset, 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, @@ -2001,6 +2094,13 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, } break; 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) { @@ -2008,6 +2108,13 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, } break; 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); break; case A_CMDQ_PROD: @@ -2015,9 +2122,22 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, smmuv3_cmdq_consume(s, &local_err, reg_sec_sid); break; case A_CMDQ_CONS: + if (!smmu_cmdq_disabled_stable(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; break; 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) { @@ -2025,24 +2145,63 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwad= dr offset, } break; 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); break; case A_EVENTQ_PROD: + if (!smmu_eventq_disabled_stable(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; break; case A_EVENTQ_CONS: bank->eventq.cons =3D data; break; 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); break; 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 >> 32; bank->eventq_irq_cfg0 =3D deposit64(bank->eventq_irq_cfg0, 32, 32,= data); break; 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; break; 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; break; default: @@ -2108,6 +2267,14 @@ static MemTxResult smmu_readll(SMMUv3State *s, hwadd= r offset, case A_EVENTQ_BASE: *data =3D bank->eventq.base; return MEMTX_OK; + case A_EVENTQ_IRQ_CFG0: + if (!smmu_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_EVTQ)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + + *data =3D bank->eventq_irq_cfg0; + return MEMTX_OK; default: *data =3D 0; qemu_log_mask(LOG_UNIMP, @@ -2229,6 +2396,38 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr= offset, case A_EVENTQ_CONS: *data =3D bank->eventq.cons; return MEMTX_OK; + case A_EVENTQ_IRQ_CFG0: /* 64b */ + if (!smmu_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_EVTQ)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + + *data =3D extract64(bank->eventq_irq_cfg0, 0, 32); + return MEMTX_OK; + case A_EVENTQ_IRQ_CFG0 + 4: + if (!smmu_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_EVTQ)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + + *data =3D extract64(bank->eventq_irq_cfg0, 32, 32); + return MEMTX_OK; + case A_EVENTQ_IRQ_CFG1: + if (!smmu_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_EVTQ)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + + *data =3D bank->eventq_irq_cfg1; + return MEMTX_OK; + case A_EVENTQ_IRQ_CFG2: + if (!smmu_irq_cfg_present(s, reg_sec_sid, SMMU_IRQ_EVTQ)) { + *data =3D 0; /* RES0 */ + return MEMTX_OK; + } + + *data =3D bank->eventq_irq_cfg2; + return MEMTX_OK; default: *data =3D 0; qemu_log_mask(LOG_UNIMP, @@ -2610,4 +2809,3 @@ static void smmuv3_register_types(void) } =20 type_init(smmuv3_register_types) - --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638560088908.7431840273395; Thu, 13 Aug 2026 09:29:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGA-0003VC-Hv; Thu, 13 Aug 2026 12:26:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYFu-0003GB-Nl; Thu, 13 Aug 2026 12:26:10 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFr-0001BV-O6; Thu, 13 Aug 2026 12:26:09 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwCnpq4d8H1qm1HmAA--.5091S2; Fri, 14 Aug 2026 00:26:05 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8Dw4XUX8H1q5iwjAA--.55915S6; Fri, 14 Aug 2026 00:26: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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 19/28] hw/arm/smmuv3: Determine register bank from MMIO offset Date: Fri, 14 Aug 2026 00:25:57 +0800 Message-Id: <20260813162558.2808607-4-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8Dw4XUX8H1q5iwjAA--.55915S6 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HqAABs+ Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxAr4rZr4xGFy7Jr43uF15Arb_yoW7Jryfpr WkJr1FgF4DKF4SqFs3Ja1DC3WxZwn2gr9Iyrn3Ka4DC3y8tw1xXay0k34furyDuFyUAws8 WrW5Gr13WF4qy3DanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638561294158500 Content-Type: text/plain; charset="utf-8" Modify the main MMIO handlers to select the target register bank from the memory-mapped offset. Offsets in the Secure register window select SMMU_SEC_SID_S and are normalized by subtracting SMMU_SECURE_REG_START. Other offsets select the Non-secure bank. Pass the selected SEC_SID to the register access helpers, where the normalized bank-local offset identifies the register. Keep bank-specific differences explicit, such as S_IDR5 being unimplemented. This patch implements Non-secure and Secure bank dispatch and prepares for later access checks; Realm and Root programming interfaces are not modeled. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index efa78869251..b36bc4a54e0 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1889,9 +1889,9 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **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); =20 switch (offset) { @@ -1959,10 +1959,10 @@ 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); =20 switch (offset) { @@ -2223,16 +2223,26 @@ 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 + /* + * Dispatch the Non-secure window directly. After access validation, + * translate the Secure window to its bank-local register offsets. + */ + if (offset >=3D SMMU_SECURE_REG_START) { + reg_sec_sid =3D SMMU_SEC_SID_S; + offset -=3D SMMU_SECURE_REG_START; + } + 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; @@ -2244,9 +2254,9 @@ static MemTxResult smmu_write_mmio(void *opaque, hwad= dr 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); =20 switch (offset) { @@ -2285,9 +2295,9 @@ static MemTxResult smmu_readll(SMMUv3State *s, hwaddr= 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); =20 switch (offset) { @@ -2295,6 +2305,10 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr= offset, *data =3D smmuv3_idreg(offset - A_IDREGS); return MEMTX_OK; case A_IDR0 ... A_IDR5: + /* IDR5 does not support Secure or Realm state. */ + if ((reg_sec_sid !=3D SMMU_SEC_SID_NS) && (offset =3D=3D A_IDR5)) { + goto unhandled; + } *data =3D bank->idr[(offset - A_IDR0) / 4]; return MEMTX_OK; case A_IIDR: @@ -2429,6 +2443,7 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr = offset, *data =3D bank->eventq_irq_cfg2; return MEMTX_OK; default: + unhandled: *data =3D 0; qemu_log_mask(LOG_UNIMP, "%s unhandled 32-bit access at 0x%"PRIx64" (RAZ)\n", @@ -2443,16 +2458,21 @@ 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; + offset -=3D SMMU_SECURE_REG_START; + } =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 Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638429804417.1098170085555; Thu, 13 Aug 2026 09:27:09 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGG-0003fx-Ng; Thu, 13 Aug 2026 12:26:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYFw-0003Lq-V3; Thu, 13 Aug 2026 12:26:14 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYFs-0001Bo-Qq; Thu, 13 Aug 2026 12:26:11 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwAnL7cd8H1qmlHmAA--.4877S2; Fri, 14 Aug 2026 00:26:05 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8Dw4XUX8H1q5iwjAA--.55915S7; Fri, 14 Aug 2026 00:26: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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 20/28] hw/arm/smmuv3: Route IRQ and GERROR handling by SEC_SID Date: Fri, 14 Aug 2026 00:25:58 +0800 Message-Id: <20260813162558.2808607-5-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8Dw4XUX8H1q5iwjAA--.55915S7 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HqgAAs9 Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxWFW5JrWfuw1DtrykCF4xXrb_yoW5tFW5pw 47K3s0gr4rt3Z8XFyrJa9rZ3W7G34ktrn8CrWYgFWfA3W5AryUXrWDu3Wj934Dury7Zw4k ZaySgFW5Zr47A3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638430453158500 Content-Type: text/plain; charset="utf-8" Interrupt and global error handling currently always selects the Non-secure register bank, even when the event or command originates from the Secure programming interface. This splits CMDQ_CONS.ERR from GERROR.CMDQ_ERR and prevents Secure software from acknowledging the error through S_GERRORN. Pass SEC_SID through the IRQ and GERROR helpers and all queue call sites so interrupt enable checks, global error reporting, and acknowledgement use the originating programming-interface bank. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index b36bc4a54e0..d69fc0898af 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -49,11 +49,11 @@ * * @irq: irq type * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR) + * @sec_sid: security state of the programming interface */ 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; @@ -90,9 +90,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; @@ -173,7 +173,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; } @@ -187,7 +187,8 @@ void smmuv3_propagate_event(SMMUv3State *s, Evt *evt, S= MMUSecSID sec_sid) QEMU_LOCK_GUARD(&s->mutex); 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); } } =20 @@ -1645,7 +1646,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp, SMMUSecSID sec_sid) 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: @@ -1879,7 +1880,8 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error = **errp, SMMUSecSID sec_sid) 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), @@ -1996,7 +1998,7 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr= offset, bank->irq_ctrl =3D data; break; 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 --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638606740418.24088947495125; Thu, 13 Aug 2026 09:30:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGL-0003qg-B0; Thu, 13 Aug 2026 12:26:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYGG-0003hX-RB; Thu, 13 Aug 2026 12:26:34 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGC-0001Jf-KZ; Thu, 13 Aug 2026 12:26:32 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwA3PvYx8H1qBVLmAA--.4964S2; Fri, 14 Aug 2026 00:26:25 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBXQw8H1q7SwjAA--.59184S3; Fri, 14 Aug 2026 00:26:24 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 21/28] hw/arm/smmuv3: Implement SMMU_S_INIT register Date: Fri, 14 Aug 2026 00:26:20 +0800 Message-Id: <20260813162624.2809349-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBXQw8H1q7SwjAA--.59184S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HrgAAs5 Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxXF1UCw47Cr1kAFyDCry3Jwb_yoWrGFyxpr ykGr15KrWYy3WSvFsI9ay8AF13u397Gry7CrZxGrWS9a4qyryqqa1ktw4a9rWDCr15G3y7 Gw4S9Fs7ur1UX3DanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638607785158500 Content-Type: text/plain; charset="utf-8" Implement read/write handlers for the SMMU_S_INIT secure-only register. Writing INV_ALL provides a mechanism for software to perform a global invalidation of ALL caches within the SMMU, including IOTLBs and configuration caches across all security states. The MMIO dispatcher decodes the target register bank from the offset and normalizes Secure-window offsets by subtracting SMMU_SECURE_REG_START before switching on the bank-local offset. S_INIT is a Secure-only register and its A_S_INIT constant is an absolute Secure-window offset, so the handler matches it using A_S_INIT - SMMU_SECURE_REG_START and rejects accesses through Non-secure banks. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 43 +++++++++++++++++++++++++++++++++++++++++++ hw/arm/trace-events | 1 + 2 files changed, 44 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index d69fc0898af..dc3fa618883 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -393,6 +393,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) +{ + SMMUState *bs =3D &s->smmu_state; + trace_smmuv3_invalidate_all_caches(); + + /* 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, @@ -2206,7 +2221,29 @@ static MemTxResult smmu_writel(SMMUv3State *s, hwadd= r offset, =20 bank->eventq_irq_cfg2 =3D data; break; + case A_S_INIT - SMMU_SECURE_REG_START: + if (reg_sec_sid !=3D SMMU_SEC_SID_S) { + goto unhandled; + } + if (data & R_S_INIT_INV_ALL_MASK) { + /* + * If SMMU_ROOT_CR0.GPCEN =3D=3D 0, a write of 1 to INV_ALL wh= en any + * SMMU_(*_)CR0.SMMUEN =3D=3D 1, .... , is CONSTRAINED UNPREDI= CTABLE + * according to (IHI 0070G.b) 6.3.62 SMMU_S_INIT, Page 465. + */ + if (!smmuv3_smmu_disabled_stable(s, SMMU_SEC_SID_NS) || + !smmuv3_smmu_disabled_stable(s, SMMU_SEC_SID_S)) { + /* CONSTRAINED UNPREDICTABLE behavior: Ignore this write */ + qemu_log_mask(LOG_GUEST_ERROR, "S_INIT write ignored: " + "(S_)CR0.SMMUEN or (S_)CR0ACK.SMMUEN is set\= n"); + return MEMTX_OK; + } + smmuv3_invalidate_all_caches(s); + } + /* Synchronous emulation: invalidation completed instantly. */ + break; default: + unhandled: qemu_log_mask(LOG_UNIMP, "%s Unexpected 32-bit access to 0x%"PRIx64" (WI)\n", __func__, offset); @@ -2444,6 +2481,12 @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr= offset, =20 *data =3D bank->eventq_irq_cfg2; return MEMTX_OK; + case A_S_INIT - SMMU_SECURE_REG_START: + if (reg_sec_sid !=3D SMMU_SEC_SID_S) { + goto unhandled; + } + *data =3D 0; + return MEMTX_OK; default: unhandled: *data =3D 0; diff --git a/hw/arm/trace-events b/hw/arm/trace-events index 7cd4eb38578..ac9f737a5e6 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -67,6 +67,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 #smmuv3-accel.c --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638574567607.5910737132821; Thu, 13 Aug 2026 09:29:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGj-000468-2J; Thu, 13 Aug 2026 12:27:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYGG-0003hx-Tx; Thu, 13 Aug 2026 12:26:34 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGF-0001Kt-87; Thu, 13 Aug 2026 12:26:32 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwAX+EA08H1qQiRvAw--.16386S2; Fri, 14 Aug 2026 00:26:28 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBXQw8H1q7SwjAA--.59184S4; Fri, 14 Aug 2026 00:26:25 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 22/28] hw/arm/smmuv3: Harden security checks in MMIO handlers Date: Fri, 14 Aug 2026 00:26:21 +0800 Message-Id: <20260813162624.2809349-2-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBXQw8H1q7SwjAA--.59184S4 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HsAAAsn Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxZryfCFy3AFW3Zr4UZw1DJrb_yoWrWr17pr WkCw1YgrWDG3W3AFs3ta1DA3WrK3ykXr13J3sxG34UZayUtw4rXF10k34YgFsrWryUZws7 Wr4fCr4xCr1jy3DanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638575378158500 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 gated by whether SECURE_IMPL is enabled. When it is disabled, all SMMU_S_* registers are read-as-zero and write-ignored. 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 improves compatibility with Arm security space handling. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index dc3fa618883..e5f0bc18415 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1605,6 +1605,12 @@ static bool smmu_eventq_irq_cfg_writable(SMMUv3State= *s, SMMUSecSID sec_sid) return smmu_irq_cfg_writable(s, sec_sid, SMMU_IRQ_EVTQ); } =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, Error **errp, SMMUSecSID se= c_sid) { SMMUState *bs =3D ARM_SMMU(s); @@ -1905,6 +1911,38 @@ static int smmuv3_cmdq_consume(SMMUv3State *s, Error= **errp, SMMUSecSID sec_sid) return 0; } =20 +/* + * Helper function for Secure register access validation. + * + * Follow S_IDR1.SECURE_IMPL accessibility rules for SMMU_S_*: + * - SECURE_IMPL =3D=3D 0: Secure state is not implemented; SMMU_S_* are = RAZ/WI to + * all accesses. + * - SECURE_IMPL =3D=3D 1: Non-secure accesses to SMMU_S_* are RAZ/WI. + */ +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. */ + if (!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) @@ -2272,6 +2310,18 @@ static MemTxResult smmu_write_mmio(void *opaque, hwa= ddr offset, uint64_t data, * translate the Secure window to its bank-local register offsets. */ 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); + /* + * RAZ/WI/RES0 are deterministic register-level behaviors and = do not + * imply a bus protocol error or abort. Therefore we acknowled= ge the + * MMIO transaction with MEMTX_OK and implement + * "Read-As-Zero / Write-Ignored" in the register model, inste= ad of + * returning MEMTX_*_ERROR which is reserved for real decode/a= ccess + * failures. + */ + return MEMTX_OK; + } reg_sec_sid =3D SMMU_SEC_SID_S; offset -=3D SMMU_SECURE_REG_START; } @@ -2508,6 +2558,11 @@ static MemTxResult smmu_read_mmio(void *opaque, hwad= dr offset, uint64_t *data, /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */ offset &=3D ~0x10000; 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; offset -=3D SMMU_SECURE_REG_START; } --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638138848461.26296185735157; Thu, 13 Aug 2026 09:22:18 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYBs-000748-0n; Thu, 13 Aug 2026 12:22:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYBm-00073l-AW; Thu, 13 Aug 2026 12:21:54 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYBk-0000FY-Ul; Thu, 13 Aug 2026 12:21:54 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwCnrxsd731qWhRvAw--.34435S2; Fri, 14 Aug 2026 00:21:49 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8Dw43MZ731q2SwjAA--.57107S3; Fri, 14 Aug 2026 00:21:46 +0800 (CST) From: Tao Tang To: "Michael S . Tsirkin" , 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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 23/28] hw/pci: Add sec-sid property to PCIDevice Date: Fri, 14 Aug 2026 00:21:45 +0800 Message-Id: <20260813162145.2800835-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8Dw43MZ731q2SwjAA--.57107S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HiQABsf Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7Cr4UJr48ZFyktw1xXF4rGrg_yoW8Zw1xpF Z3CFyIkFn5Ga4Ikws2qa1xCrZruFZ7K3yYkrWj9w17CF1xAry3Xw45KFWj9r40qrWvgF1Y ka42kFy8ur1DJFJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638144935158500 Content-Type: text/plain; charset="utf-8" Arm SMMUv3 uses a SEC_SID (StreamID Security state) to determine the security state of the programming interface that controls a transaction. The architecture explicitly states that the association between a device and its SEC_SID is a system-defined property, not something derived from the physical address space. We need a way to represent this system-defined SEC_SID for PCI devices if we want to implement SMMU's Secure state. So that SMMUv3 can select the correct register bank and configuration when handling their streams. This patch adds a new char *sec_sid field to PCIDevice, together with a "sec-sid" QOM property. The property is intended to carry the platform-defined SEC_SID for the device; for now only Non-secure and Secure security states are supported. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/pci/pci.c | 7 +++++++ include/hw/pci/pci_device.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index d3191609e28..b86135af96d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -104,6 +104,13 @@ static const Property pci_props[] =3D { DEFINE_PROP_STRING("sriov-pf", PCIDevice, sriov_pf), DEFINE_PROP_BIT("x-pcie-ext-tag", PCIDevice, cap_present, QEMU_PCIE_EXT_TAG_BITNR, true), + + /* + * System-defined, statically configured SEC_SID for this PCI device, = used + * by Arm SMMU. Only support "non-secure" and "secure" security states. + */ + DEFINE_PROP_STRING("sec-sid", PCIDevice, sec_sid), + { .name =3D "busnr", .info =3D &prop_pci_busnr }, }; =20 diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h index 5cac6e16886..6e6c49fdd19 100644 --- a/include/hw/pci/pci_device.h +++ b/include/hw/pci/pci_device.h @@ -187,6 +187,9 @@ struct PCIDevice { uint32_t max_bounce_buffer_size; =20 char *sriov_pf; + + /* Arm SMMU SEC_SID */ + char *sec_sid; }; =20 static inline int pci_intx(PCIDevice *pci_dev) --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638632852912.8283256210817; Thu, 13 Aug 2026 09:30:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGt-0004Oi-Od; Thu, 13 Aug 2026 12:27:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYGI-0003kV-R5; Thu, 13 Aug 2026 12:26:36 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGG-0001Ln-Ru; Thu, 13 Aug 2026 12:26:34 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwBnbBg18H1qUiRvAw--.34360S2; Fri, 14 Aug 2026 00:26:29 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBXQw8H1q7SwjAA--.59184S5; Fri, 14 Aug 2026 00:26:28 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 24/28] hw/arm/smmuv3: Select sec-sid from PCI property and validate SECURE_IMPL Date: Fri, 14 Aug 2026 00:26:22 +0800 Message-Id: <20260813162624.2809349-3-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBXQw8H1q7SwjAA--.59184S5 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HsgAAsl Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3AFyxAFWfXFyfXrykWr13twb_yoW3CrykpF WUJF45KrW8GF93AFs3tw429a1Yqws7W3W5JrW3Kas5C34Utr18Jr4vka4YvrZ8WrW5Aa17 ZayIgFWDur12yrJanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638634008158500 Content-Type: text/plain; charset="utf-8" Parse each PCI device's sec-sid property during SMMU device initialization and cache it in SMMUDevice::sec_sid. Support "non-secure" and "secure", default to non-secure when unspecified, and reject invalid values with an explicit error. Use sdev->sec_sid in smmuv3_translate() to select the register bank instead of hardcoding the non-secure context. Keep sec-sid parsing in smmu-common, and add a SMMUv3-specific validation hook to enforce architectural constraints: fail fast when sec-sid=3Dsecure while SMMU_S_IDR1.SECURE_IMPL is 0 or secure AS is not available. Typically, SEC_SID is a system-defined attribute (e.g. sideband or tied-off) rather than something a PCIe endpoint can freely toggle in pre-RME scenario. So this PCI sec-sid property is used as a static platform/testing knob to drive the SMMU bank selection. For future RME-DA and TDISP support, this static property will need to be replaced by runtime platform plumbing that derives the effective SEC_SID from the device security assignment. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 37 ++++++++++++++++++++++ hw/arm/smmuv3.c | 61 +++++++++++++++++++++++++++++++++++- include/hw/arm/smmu-common.h | 2 ++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index e8a1ed65c19..4a94799fb0d 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -21,6 +21,7 @@ #include "exec/target_page.h" #include "hw/core/cpu.h" #include "hw/pci/pci_bridge.h" +#include "hw/pci/pci_device.h" #include "hw/core/qdev-properties.h" #include "qapi/error.h" #include "qemu/jhash.h" @@ -1100,14 +1101,50 @@ SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uin= t8_t bus_num) return NULL; } =20 +static SMMUSecSID smmu_parse_pci_sec_sid(PCIDevice *pdev, int bus_num, + int devfn) +{ + const char *sec_sid; + + if (!pdev || !pdev->sec_sid) { + return SMMU_SEC_SID_NS; + } + + sec_sid =3D pdev->sec_sid; + if (!strcmp(sec_sid, "non-secure")) { + return SMMU_SEC_SID_NS; + } + if (!strcmp(sec_sid, "secure")) { + return SMMU_SEC_SID_S; + } + + error_report("Invalid sec-sid value '%s' for PCI device %02x:%02x.%x; " + "allowed values: non-secure or secure (case-sensitive)", + sec_sid, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); + exit(EXIT_FAILURE); +} + void smmu_init_sdev(SMMUState *s, SMMUDevice *sdev, PCIBus *bus, int devfn) { static unsigned int index; g_autofree char *name =3D g_strdup_printf("%s-%d-%d", s->mrtypename, d= evfn, index++); + SMMUBaseClass *sbc =3D ARM_SMMU_GET_CLASS(s); + PCIDevice *pdev; + int bus_num; + sdev->smmu =3D s; sdev->bus =3D bus; sdev->devfn =3D devfn; + sdev->sec_sid =3D SMMU_SEC_SID_NS; + + bus_num =3D pci_bus_num(bus); + pdev =3D pci_find_device(bus, bus_num, devfn); + sdev->sec_sid =3D smmu_parse_pci_sec_sid(pdev, bus_num, devfn); + if (sbc->validate_sec_sid && + !sbc->validate_sec_sid(s, sdev, bus_num)) { + exit(EXIT_FAILURE); + } =20 memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu), s->mrtypename, OBJECT(s), name, UINT64_MAX); diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index e5f0bc18415..a755f1ebd69 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -43,6 +43,12 @@ ((ptw_info).stage =3D=3D SMMU_STAG= E_2 && \ (cfg)->s2cfg.record_faults)) =20 +enum { + SMMU_IOMMU_IDX_NS, + SMMU_IOMMU_IDX_S, + SMMU_IOMMU_IDX_NUM, +}; + /** * smmuv3_trigger_irq - pulse @irq if enabled and update * GERROR register in case of GERROR interrupt @@ -1157,6 +1163,33 @@ static void smmuv3_fixup_event(SMMUEventInfo *event,= hwaddr iova) } } =20 +static int smmuv3_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attr= s) +{ + if (attrs.unspecified) { + return SMMU_IOMMU_IDX_NS; + } + return attrs.secure ? SMMU_IOMMU_IDX_S : SMMU_IOMMU_IDX_NS; +} + +static int smmuv3_num_indexes(IOMMUMemoryRegion *iommu) +{ + return SMMU_IOMMU_IDX_NUM; +} + +static AddressSpace *smmuv3_bypass_target_as(SMMUv3State *s, + SMMUSecSID sec_sid, + int iommu_idx) +{ + g_assert(iommu_idx >=3D SMMU_IOMMU_IDX_NS && + iommu_idx < SMMU_IOMMU_IDX_NUM); + + if (smmu_sec_sid_is_secure(sec_sid) && + iommu_idx =3D=3D SMMU_IOMMU_IDX_S) { + return smmu_get_address_space(&s->smmu_state, SMMU_SEC_SID_S); + } + return smmu_get_address_space(&s->smmu_state, SMMU_SEC_SID_NS); +} + /* Entry point to SMMU, does everything. */ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr, IOMMUAccessFlags flag, int iommu_idx) @@ -1164,7 +1197,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 sdev->sec_sid; SMMUv3RegBank *bank =3D smmuv3_bank(s, sec_sid); SMMUEventInfo event =3D {.type =3D SMMU_EVT_NONE, .sid =3D sid, @@ -1181,6 +1214,8 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegi= on *mr, hwaddr addr, }; SMMUTLBEntry *cached_entry =3D NULL; =20 + entry.target_as =3D smmuv3_bypass_target_as(s, sec_sid, iommu_idx); + qemu_mutex_lock(&s->mutex); =20 if (!smmu_enabled(s, sec_sid)) { @@ -1611,6 +1646,26 @@ static inline bool smmu_hw_secure_implemented(SMMUv3= State *s) return FIELD_EX32(s->bank[SMMU_SEC_SID_S].idr[1], S_IDR1, SECURE_IMPL); } =20 +static bool smmuv3_validate_sec_sid(SMMUState *bs, SMMUDevice *sdev, + int bus_num) +{ + SMMUv3State *s =3D ARM_SMMUV3(bs); + + if (sdev->sec_sid !=3D SMMU_SEC_SID_S) { + return true; + } + + if (!smmu_hw_secure_implemented(s)) { + error_report("Invalid sec-sid value 'secure' for PCI device " + "%02x:%02x.%x: S_IDR1.SECURE_IMPL is 0, so only " + "non-secure is allowed", + bus_num, PCI_SLOT(sdev->devfn), PCI_FUNC(sdev->devfn)= ); + return false; + } + + return true; +} + static int smmuv3_cmdq_consume(SMMUv3State *s, Error **errp, SMMUSecSID se= c_sid) { SMMUState *bs =3D ARM_SMMU(s); @@ -2823,6 +2878,7 @@ static void smmuv3_class_init(ObjectClass *klass, con= st void *data) DeviceClass *dc =3D DEVICE_CLASS(klass); ResettableClass *rc =3D RESETTABLE_CLASS(klass); SMMUv3Class *c =3D ARM_SMMUV3_CLASS(klass); + SMMUBaseClass *sbc =3D ARM_SMMU_CLASS(klass); =20 dc->vmsd =3D &vmstate_smmuv3; resettable_class_set_parent_phases(rc, NULL, NULL, smmu_reset_exit, @@ -2832,6 +2888,7 @@ static void smmuv3_class_init(ObjectClass *klass, con= st void *data) device_class_set_props(dc, smmuv3_properties); dc->hotpluggable =3D false; dc->user_creatable =3D true; + sbc->validate_sec_sid =3D smmuv3_validate_sec_sid; =20 object_class_property_set_description(klass, "accel", "Enable SMMUv3 accelerator support. Allows host SMMUv3 to be " @@ -2905,6 +2962,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 { diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index a21c6061808..9da54221f20 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -134,6 +134,7 @@ typedef struct SMMUDevice { void *smmu; PCIBus *bus; int devfn; + SMMUSecSID sec_sid; IOMMUMemoryRegion iommu; AddressSpace as; uint32_t cfg_cache_hits; @@ -204,6 +205,7 @@ struct SMMUBaseClass { /*< public >*/ =20 DeviceRealize parent_realize; + bool (*validate_sec_sid)(struct SMMUState *s, SMMUDevice *sdev, int bu= s_num); =20 }; =20 --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638555215426.8303924621307; Thu, 13 Aug 2026 09:29:15 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGM-0003vM-MX; Thu, 13 Aug 2026 12:26:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYGJ-0003lk-3L; Thu, 13 Aug 2026 12:26:36 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGH-0001Mt-LS; Thu, 13 Aug 2026 12:26:34 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwCXl6838H1qJlLmAA--.4975S2; Fri, 14 Aug 2026 00:26:31 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBXQw8H1q7SwjAA--.59184S6; Fri, 14 Aug 2026 00:26:29 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 25/28] hw/arm/smmuv3: Reject IOMMU notifiers for non-NS devices Date: Fri, 14 Aug 2026 00:26:23 +0800 Message-Id: <20260813162624.2809349-4-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBXQw8H1q7SwjAA--.59184S6 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HtAAAsj Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvdXoW7Jry8uw1xAr1DAFWxZF4rGrg_yoWftFgE9F 4rX395Wr1IyFyIk3sxtr4xAryYvw4rCr15uF4xu3WxG3WDA34UX34DArykXw13Zryxur4Y yrZ5u3W5ArnFgjkaLaAFLSUrUUUU1b8apTn2vfkv8UJUUUU8wcxFpf9Il3svdxBIdaVrnU 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=lists1p.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, 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: 1786638557224158500 Content-Type: text/plain; charset="utf-8" VFIO and vhost IOMMU notifiers currently support only the Non-secure system-memory path. Reject notifier registration for non-NS devices instead of allowing an unsupported configuration. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index a755f1ebd69..2375b7a17a0 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -2932,6 +2932,13 @@ static int smmuv3_notify_flag_changed(IOMMUMemoryReg= ion *iommu, SMMUv3State *s3 =3D sdev->smmu; SMMUState *s =3D &(s3->smmu_state); =20 + if (new !=3D IOMMU_NOTIFIER_NONE && sdev->sec_sid !=3D SMMU_SEC_SID_NS= ) { + error_setg(errp, + "SMMUv3 does not support IOMMU notifiers for " + "secure devices"); + return -EINVAL; + } + if (new & IOMMU_NOTIFIER_DEVIOTLB_UNMAP) { error_setg(errp, "SMMUv3 does not support dev-iotlb yet"); return -EINVAL; --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178663863559757.99579345564939; Thu, 13 Aug 2026 09:30:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGt-0004Oj-Od; Thu, 13 Aug 2026 12:27:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYGe-00044D-Ej; Thu, 13 Aug 2026 12:27:00 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGc-0001NA-VY; Thu, 13 Aug 2026 12:26:56 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-6 (Coremail) with UTF8SMTP id AQAAfwCnpq428H1qIVLmAA--.5092S2; Fri, 14 Aug 2026 00:26:30 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwBXQw8H1q7SwjAA--.59184S7; Fri, 14 Aug 2026 00:26:29 +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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 26/28] hw/arm/smmuv3: Initialize the secure register bank Date: Fri, 14 Aug 2026 00:26:24 +0800 Message-Id: <20260813162624.2809349-5-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwBXQw8H1q7SwjAA--.59184S7 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HtAABsi Authentication-Results: hzbj-icmmx-6; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoWxGF15GFWfArW7ur4UuFyDZFb_yoW5Ww18pF ZrAr15Kw13KFn3X3y3A3y8AF13Wr4xtw1DCr9xWF1rC345KrWUJr4DGFyFvrZFvr1rua12 qFySg3y5Wr45A3DanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638638159158500 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 Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 2375b7a17a0..7e7376c65e2 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -293,6 +293,7 @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo = *info) static void smmuv3_init_id_regs(SMMUv3State *s) { SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + SMMUv3RegBank *sbank =3D smmuv3_bank(s, SMMU_SEC_SID_S); =20 /* Based on sys property, the stages supported in smmu will be adverti= sed.*/ if (s->stage && !strcmp("2", s->stage)) { @@ -339,7 +340,14 @@ static void smmuv3_init_id_regs(SMMUv3State *s) bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, GRAN4K, 1); bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, GRAN16K, 1); bank->idr[5] =3D FIELD_DP32(bank->idr[5], IDR5, GRAN64K, 1); - s->aidr =3D 0x1; + + /* Initialize Secure bank */ + memset(sbank->idr, 0, sizeof(sbank->idr)); + /* No stall */ + sbank->idr[0] =3D FIELD_DP32(sbank->idr[0], S_IDR0, STALL_MODEL, 1); + + sbank->idr[1] =3D FIELD_DP32(sbank->idr[1], S_IDR1, S_SIDSIZE, + SMMU_IDR1_SIDSIZE); smmuv3_accel_idr_override(s); } =20 @@ -352,6 +360,7 @@ bool smmuv3_ats_enabled(SMMUv3State *s) static void smmuv3_reset(SMMUv3State *s) { SMMUv3RegBank *bank =3D smmuv3_bank(s, SMMU_SEC_SID_NS); + SMMUv3RegBank *sbank =3D smmuv3_bank(s, SMMU_SEC_SID_S); =20 bank->cmdq.base =3D deposit64(bank->cmdq.base, 0, 5, SMMU_CMDQS); bank->cmdq.prod =3D 0; @@ -371,6 +380,24 @@ static void smmuv3_reset(SMMUv3State *s) bank->gerrorn =3D 0; bank->gbpa =3D SMMU_GBPA_RESET_VAL; =20 + sbank->cmdq.base =3D deposit64(sbank->cmdq.base, 0, 5, SMMU_CMDQS); + sbank->cmdq.prod =3D 0; + sbank->cmdq.cons =3D 0; + sbank->cmdq.entry_size =3D sizeof(struct Cmd); + sbank->eventq.base =3D deposit64(sbank->eventq.base, 0, 5, SMMU_EVENTQ= S); + sbank->eventq.prod =3D 0; + sbank->eventq.cons =3D 0; + sbank->eventq.entry_size =3D sizeof(struct Evt); + + sbank->features =3D 0; + sbank->sid_split =3D 0; + sbank->cr[0] =3D 0; + sbank->cr0ack =3D 0; + sbank->irq_ctrl =3D 0; + sbank->gerror =3D 0; + sbank->gerrorn =3D 0; + sbank->gbpa =3D SMMU_GBPA_RESET_VAL; + s->aidr =3D 0x1; s->statusr =3D 0; } --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638543354370.3287060482878; Thu, 13 Aug 2026 09:29:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYH6-0004eH-No; Thu, 13 Aug 2026 12:27:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYGc-000441-Tf; Thu, 13 Aug 2026 12:27:00 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGb-0001Qm-8q; Thu, 13 Aug 2026 12:26:54 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwCHj1NK8H1qTyVvAw--.34755S2; Fri, 14 Aug 2026 00:26:50 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwoHJE8H1q7ywjAA--.56307S3; Fri, 14 Aug 2026 00:26: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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 27/28] hw/arm/smmuv3: Add secure bank migration and secure-impl property Date: Fri, 14 Aug 2026 00:26:43 +0800 Message-Id: <20260813162644.2810021-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwoHJE8H1q7ywjAA--.56307S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HtwAAsg Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3GrWxGw1fKFW3AFWkAFyfCrg_yoW7AF4Dpr s8Gwn8GryUGF43Zr43J3WrCFs5Cr4xGa1YkrWDCa9aya1ktF42qwn7A3yFg3ykGrW8Xa1x uF1xuFZrJr47ZrJanT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638545210158500 Content-Type: text/plain; charset="utf-8" Add a secure-impl device property and advertise it through S_IDR1.SECURE_IMPL. Reject secure-impl=3Don unless Secure memory is availab= le and stage-1 translation is supported. Usage: -M virt,secure=3Don,iommu=3Dsmmuv3 \ -global arm-smmuv3.secure-impl=3Don Add the smmuv3/bank_s migration subsection for the secure register bank. Serialize secure bank state including GBPA, IRQ config, stream table and queue state. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier Reviewed-by: Jim MacArthur Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 93 +++++++++++++++++++++++++++++++++++++++++ include/hw/arm/smmuv3.h | 2 + 2 files changed, 95 insertions(+) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 7e7376c65e2..8e1de94fd17 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -348,6 +348,8 @@ static void smmuv3_init_id_regs(SMMUv3State *s) =20 sbank->idr[1] =3D FIELD_DP32(sbank->idr[1], S_IDR1, S_SIDSIZE, SMMU_IDR1_SIDSIZE); + sbank->idr[1] =3D FIELD_DP32(sbank->idr[1], S_IDR1, SECURE_IMPL, + s->secure_impl =3D=3D ON_OFF_AUTO_ON); smmuv3_accel_idr_override(s); } =20 @@ -2752,6 +2754,37 @@ static bool smmu_validate_property(SMMUv3State *s, E= rror **errp) return true; } =20 +static bool smmuv3_resolve_secure_impl(SMMUv3State *s, Error **errp) +{ + SMMUState *bs =3D ARM_SMMU(s); + bool secure_as_available =3D bs->secure_memory && + bs->secure_memory_as.root !=3D NULL; + + if (s->secure_impl =3D=3D ON_OFF_AUTO_AUTO) { + s->secure_impl =3D secure_as_available ? ON_OFF_AUTO_ON + : ON_OFF_AUTO_OFF; + } + + if (s->secure_impl =3D=3D ON_OFF_AUTO_ON && !secure_as_available) { + error_setg(errp, + "secure-impl=3Don requires a secure-memory address spac= e"); + return false; + } + + /* + * When SECURE_IMPL =3D=3D 1, stage 1 must be supported according to + * (IHI 0070G.b) 6.3.53 SMMU_S_IDR1, Page 442. + */ + if (s->secure_impl =3D=3D ON_OFF_AUTO_ON && + s->stage && !strcmp(s->stage, "2")) { + error_setg(errp, + "secure-impl=3Don requires stage=3D1 or stage=3Dnested= "); + return false; + } + + return true; +} + static void smmu_realize(DeviceState *d, Error **errp) { SMMUState *sys =3D ARM_SMMU(d); @@ -2781,6 +2814,10 @@ static void smmu_realize(DeviceState *d, Error **err= p) return; } =20 + if (!smmuv3_resolve_secure_impl(s, errp)) { + return; + } + qemu_mutex_init(&s->mutex); =20 memory_region_init_io(&sys->iomem, OBJECT(s), @@ -2807,6 +2844,54 @@ 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(gbpa, 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 =3D=3D ON_OFF_AUTO_ON; +} + +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; @@ -2861,6 +2946,7 @@ static const VMStateDescription vmstate_smmuv3 =3D { }, .subsections =3D (const VMStateDescription * const []) { &vmstate_gbpa, + &vmstate_smmuv3_bank_s, NULL } }; @@ -2893,6 +2979,13 @@ static const Property smmuv3_properties[] =3D { DEFINE_PROP_SSIDSIZE_MODE("ssidsize", SMMUv3State, ssidsize, SSID_SIZE_MODE_AUTO), DEFINE_PROP_ON_OFF_AUTO("cmdqv", SMMUv3State, cmdqv, ON_OFF_AUTO_AUTO), + /* + * SECURE_IMPL field in S_IDR1 register. + * Indicates whether secure state is implemented. + * Defaults to auto. + */ + DEFINE_PROP_ON_OFF_AUTO("secure-impl", SMMUv3State, secure_impl, + ON_OFF_AUTO_AUTO), }; =20 static void smmuv3_instance_init(Object *obj) diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index 8cd2edc3412..9b533b9a99b 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -81,6 +81,8 @@ struct SMMUv3State { OnOffAuto ats; OasMode oas; SsidSizeMode ssidsize; + OnOffAuto secure_impl; + /* SMMU CMDQV extension */ OnOffAuto cmdqv; =20 --=20 2.34.1 From nobody Fri Aug 28 00:14:17 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1786638600076247.8006362309344; Thu, 13 Aug 2026 09:30:00 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYHA-0004kz-D6; Thu, 13 Aug 2026 12:27:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wuYGb-00043S-Fe; Thu, 13 Aug 2026 12:26:54 -0400 Received: from zg8tmtyylji0my4xnjqumte4.icoremail.net ([162.243.164.118]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wuYGZ-0001QG-Ep; Thu, 13 Aug 2026 12:26:53 -0400 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with UTF8SMTP id AQAAfwCnrxtI8H1qNCVvAw--.34509S2; Fri, 14 Aug 2026 00:26:48 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAf8DwoHJE8H1q7ywjAA--.56307S4; Fri, 14 Aug 2026 00:26: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?= , Mostafa Saleh , Chao Liu , Jim MacArthur , Tao Tang Subject: [RFC v5 28/28] [NOT-MERGE] hw/arm/smmuv3: temporarily enable SEL2 bit and some other features Date: Fri, 14 Aug 2026 00:26:44 +0800 Message-Id: <20260813162644.2810021-2-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> References: <20260813161515.2788900-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8DwoHJE8H1q7ywjAA--.56307S4 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQAGBWp8yc0HtwABsh Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW7KFyrCw1fXryxtF13Gr1xZrb_yoW8XryDpa 1DAryDKayvkw43Z34UAw4xA3W3Gan5Gr12yr4DWrWrA3WYvr1DJw4vgw1rKryI9rWrAF47 uF1I9a9Yqr1Fqr7anT9S1TB71UUUUUDqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj 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=lists1p.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, 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: 1786638601573158500 Content-Type: text/plain; charset="utf-8" Temporarily: - enable S_IDR1.SEL2, - change AIDR to 0x2 to indicate SMMUv3.2, - use smaller SID size and Cmd/Evt queue size. Signed-off-by: Tao Tang Tested-by: Pierrick Bouvier --- hw/arm/smmuv3.c | 3 ++- include/hw/arm/smmuv3-common.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 8e1de94fd17..19e080b6d25 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -350,6 +350,7 @@ static void smmuv3_init_id_regs(SMMUv3State *s) SMMU_IDR1_SIDSIZE); sbank->idr[1] =3D FIELD_DP32(sbank->idr[1], S_IDR1, SECURE_IMPL, s->secure_impl =3D=3D ON_OFF_AUTO_ON); + sbank->idr[1] =3D FIELD_DP32(sbank->idr[1], S_IDR1, SEL2, 1); smmuv3_accel_idr_override(s); } =20 @@ -400,7 +401,7 @@ static void smmuv3_reset(SMMUv3State *s) sbank->gerrorn =3D 0; sbank->gbpa =3D SMMU_GBPA_RESET_VAL; =20 - s->aidr =3D 0x1; + s->aidr =3D 0x2; /* SMMUv3.2 */ s->statusr =3D 0; } =20 diff --git a/include/hw/arm/smmuv3-common.h b/include/hw/arm/smmuv3-common.h index ec442a85586..1afaece3df7 100644 --- a/include/hw/arm/smmuv3-common.h +++ b/include/hw/arm/smmuv3-common.h @@ -311,9 +311,9 @@ REG32(IDR1, 0x4) FIELD(IDR1, TABLES_PRESET, 30, 1) FIELD(IDR1, ECMDQ, 31, 1) =20 -#define SMMU_IDR1_SIDSIZE 16 -#define SMMU_CMDQS 19 -#define SMMU_EVENTQS 19 +#define SMMU_IDR1_SIDSIZE 6 +#define SMMU_CMDQS 10 +#define SMMU_EVENTQS 10 =20 REG32(IDR2, 0x8) FIELD(IDR2, BA_VATOS, 0, 10) --=20 2.34.1