From nobody Sun Apr 12 04:28:46 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771669189143783.029364425758; Sat, 21 Feb 2026 02:19:49 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vtk58-0003zT-CW; Sat, 21 Feb 2026 05:19:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vtk52-0003gP-Dc; Sat, 21 Feb 2026 05:19:21 -0500 Received: from sgoci-sdnproxy-4.icoremail.net ([129.150.39.64]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vtk4z-0004hB-U6; Sat, 21 Feb 2026 05:19:20 -0500 Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-7 (Coremail) with SMTP id AQAAfwCXnJihhplpVrBVBw--.3782S2; Sat, 21 Feb 2026 18:19:13 +0800 (CST) Received: from phytium.com.cn (unknown [218.76.62.144]) by mail (Coremail) with SMTP id AQAAfwDXMO6ehplpg04cAA--.34423S3; Sat, 21 Feb 2026 18:19:10 +0800 (CST) From: Tao Tang To: Eric Auger , Peter Maydell , "Michael S . Tsirkin" , Marcel Apfelbaum Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org, Chen Baozi , Pierrick Bouvier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Mostafa Saleh , Chao Liu , Tao Tang Subject: [RFC v4 28/31] hw/arm/smmuv3: Select sec-sid from PCI property and validate SECURE_IMPL Date: Sat, 21 Feb 2026 18:19:07 +0800 Message-Id: <20260221101907.2997408-1-tangtao1634@phytium.com.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260221100250.2976287-1-tangtao1634@phytium.com.cn> References: <20260221100250.2976287-1-tangtao1634@phytium.com.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAfwDXMO6ehplpg04cAA--.34423S3 X-CM-SenderInfo: pwdqw3tdrrljuu6sx5pwlxzhxfrphubq/1tbiAQANBWmYzyUATQAAsf Authentication-Results: hzbj-icmmx-7; spf=neutral smtp.mail=tangtao163 4@phytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvJXoW3AFyxAFWfXFWfKryfuFW5GFg_yoWxXF1kpF W8AFn8tryUGF93ursayw4293WYqan7GF1fJrW3ua95C347JrykJr40kw12vrWDWrWqya17 ZayIgFWDur17ZrJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAU7a7-sFnT9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUU UUUUU Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=129.150.39.64; envelope-from=tangtao1634@phytium.com.cn; helo=sgoci-sdnproxy-4.icoremail.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1771669191268158500 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 + TDISP, this will need to become dynamic: the effective state for PCIe requests is derived from PCIe IDE/TDISP T/XT (e.g. SEC_SID =3D (XT || T) ? Realm : Non-secure), so we'll switch from a static property to a runtime per-device state update when that plumbing is added. Signed-off-by: Tao Tang Reviewed-by: Pierrick Bouvier --- hw/arm/smmu-common.c | 37 ++++++++++++++++++++++++++++++++++++ hw/arm/smmuv3.c | 34 ++++++++++++++++++++++++++++++++- include/hw/arm/smmu-common.h | 2 ++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 5dece2024a4..b0a238abe93 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" @@ -1071,14 +1072,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 0b8ea922851..57a063b5e5d 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1116,7 +1116,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, @@ -1509,6 +1509,36 @@ 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); + bool secure_as_available =3D bs->secure_memory && + bs->secure_memory_as.root !=3D NULL; + + 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; + } + + if (!secure_as_available) { + error_report("Invalid sec-sid value 'secure' for PCI device " + "%02x:%02x.%x: secure-memory address space is not " + "configured", + 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); @@ -2664,6 +2694,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, @@ -2673,6 +2704,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 " diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index d05cf6ae53b..c74f66a1bb9 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -144,6 +144,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