From nobody Mon Feb 9 11:31:59 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; dmarc=fail(p=none dis=none) header.from=huawei.com ARC-Seal: i=1; a=rsa-sha256; t=1616657270; cv=none; d=zohomail.com; s=zohoarc; b=K1RdpTlniL9xrAUOtMRPcn2BDh7wLDEA4uFKYU4sHyOJPWseVTq+ucB5UncpCUCtFd4fl6huX6xpYrZJLlqolOeWpsDd9vOylKFDIBL27401BKzugltw1n728nV52zYfIs41rwxIzziq5pU2Ps/4aLO9kJFeV0nvlO0pt6FbT+U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1616657270; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=JhbIrWh5ZZ3wxi53lYDZdzTKAgGCFY/dJ0fRVI5+k1c=; b=crWMOW8iIGsqiOgT8JBeuSJFT7cRxnbXZRiKtl+5mjY5tjSdxY2zT6GYuCiofU0fsJmQ7e3xEypXxttBIdE0AOCIGbBXJzKew26W8Jmc/XOHMj28c0HUF6rnLLeBwJst3xFm+SX90TnEHrbfcrll6o8yZdmyEmkUwYg1UXWR6ag= ARC-Authentication-Results: i=1; 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; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1616657270563569.5841872633672; Thu, 25 Mar 2021 00:27:50 -0700 (PDT) Received: from localhost ([::1]:35534 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lPKPF-0001Rt-Ip for importer@patchew.org; Thu, 25 Mar 2021 03:27:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53096) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPKKy-0004Tm-NG; Thu, 25 Mar 2021 03:23:24 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:4398) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPKKw-00032j-A8; Thu, 25 Mar 2021 03:23:24 -0400 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4F5c3L0kwRz19JDy; Thu, 25 Mar 2021 15:21:18 +0800 (CST) Received: from huawei.com (10.174.185.226) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.498.0; Thu, 25 Mar 2021 15:23:08 +0800 From: Wang Xingang To: , , , , , , , , , , Subject: [PATCH RFC RESEND v2 4/6] hw/arm/virt-acpi-build: Add explicit idmap info in IORT table Date: Thu, 25 Mar 2021 07:22:43 +0000 Message-ID: <1616656965-23328-5-git-send-email-wangxingang5@huawei.com> X-Mailer: git-send-email 2.6.4.windows.1 In-Reply-To: <1616656965-23328-1-git-send-email-wangxingang5@huawei.com> References: <1616656965-23328-1-git-send-email-wangxingang5@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.174.185.226] X-CFilter-Loop: Reflected 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=45.249.212.190; envelope-from=wangxingang5@huawei.com; helo=szxga04-in.huawei.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, 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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: xieyingtai@huawei.com, cenjiahui@huawei.com, wangxingang5@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Xingang Wang The idmap of smmuv3 and root complex covers the whole RID space for now, this patch add explicit idmap info according to root bus number range. This add smmuv3 idmap for certain bus which has enabled the iommu property. Signed-off-by: Xingang Wang Signed-off-by: Jiahui Cen --- hw/arm/virt-acpi-build.c | 103 ++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index f5a2b2d4cb..5491036c86 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -44,6 +44,7 @@ #include "hw/acpi/tpm.h" #include "hw/pci/pcie_host.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" #include "hw/pci-host/gpex.h" #include "hw/arm/virt.h" #include "hw/mem/nvdimm.h" @@ -237,6 +238,41 @@ static void acpi_dsdt_add_tpm(Aml *scope, VirtMachineS= tate *vms) aml_append(scope, dev); } =20 +typedef +struct AcpiIortMapping { + AcpiIortIdMapping idmap; + bool iommu; +} AcpiIortMapping; + +/* For all PCI host bridges, walk and insert DMAR scope */ +static int +iort_host_bridges(Object *obj, void *opaque) +{ + GArray *map_blob =3D opaque; + AcpiIortMapping map; + AcpiIortIdMapping *idmap =3D &map.idmap; + int bus_num, max_bus; + + if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) { + PCIBus *bus =3D PCI_HOST_BRIDGE(obj)->bus; + + if (bus) { + bus_num =3D pci_bus_num(bus); + max_bus =3D pci_root_bus_max_bus(bus); + + idmap->input_base =3D cpu_to_le32(bus_num << 8); + idmap->id_count =3D cpu_to_le32((max_bus - bus_num + 1) << 8); + idmap->output_base =3D cpu_to_le32(bus_num << 8); + idmap->flags =3D cpu_to_le32(0); + + map.iommu =3D pci_root_bus_has_iommu(bus); + g_array_append_val(map_blob, map); + } + } + + return 0; +} + static void build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { @@ -247,6 +283,21 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vir= tMachineState *vms) AcpiIortSmmu3 *smmu; size_t node_size, iort_node_offset, iort_length, smmu_offset =3D 0; AcpiIortRC *rc; + int smmu_mapping_count; + GArray *map_blob =3D g_array_new(false, true, sizeof(AcpiIortMapping)); + AcpiIortMapping *map; + + /* pci_for_each_bus(vms->bus, insert_map, map_blob); */ + object_child_foreach_recursive(object_get_root(), + iort_host_bridges, map_blob); + + smmu_mapping_count =3D 0; + for (int i =3D 0; i < map_blob->len; i++) { + map =3D &g_array_index(map_blob, AcpiIortMapping, i); + if (map->iommu) { + smmu_mapping_count++; + } + } =20 iort =3D acpi_data_push(table_data, sizeof(*iort)); =20 @@ -280,13 +331,13 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) =20 /* SMMUv3 node */ smmu_offset =3D iort_node_offset + node_size; - node_size =3D sizeof(*smmu) + sizeof(*idmap); + node_size =3D sizeof(*smmu) + sizeof(*idmap) * smmu_mapping_count; iort_length +=3D node_size; smmu =3D acpi_data_push(table_data, node_size); =20 smmu->type =3D ACPI_IORT_NODE_SMMU_V3; smmu->length =3D cpu_to_le16(node_size); - smmu->mapping_count =3D cpu_to_le32(1); + smmu->mapping_count =3D cpu_to_le32(smmu_mapping_count); smmu->mapping_offset =3D cpu_to_le32(sizeof(*smmu)); smmu->base_address =3D cpu_to_le64(vms->memmap[VIRT_SMMU].base); smmu->flags =3D cpu_to_le32(ACPI_IORT_SMMU_V3_COHACC_OVERRIDE); @@ -295,23 +346,28 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) smmu->gerr_gsiv =3D cpu_to_le32(irq + 2); smmu->sync_gsiv =3D cpu_to_le32(irq + 3); =20 - /* Identity RID mapping covering the whole input RID range */ - idmap =3D &smmu->id_mapping_array[0]; - idmap->input_base =3D 0; - idmap->id_count =3D cpu_to_le32(0xFFFF); - idmap->output_base =3D 0; - /* output IORT node is the ITS group node (the first node) */ - idmap->output_reference =3D cpu_to_le32(iort_node_offset); + for (int i =3D 0, j =3D 0; i < map_blob->len; i++) { + map =3D &g_array_index(map_blob, AcpiIortMapping, i); + + if (!map->iommu) { + continue; + } + + idmap =3D &smmu->id_mapping_array[j++]; + *idmap =3D map->idmap; + /* output IORT node is the ITS group node (the first node) */ + idmap->output_reference =3D cpu_to_le32(iort_node_offset); + } } =20 /* Root Complex Node */ - node_size =3D sizeof(*rc) + sizeof(*idmap); + node_size =3D sizeof(*rc) + sizeof(*idmap) * map_blob->len; iort_length +=3D node_size; rc =3D acpi_data_push(table_data, node_size); =20 rc->type =3D ACPI_IORT_NODE_PCI_ROOT_COMPLEX; rc->length =3D cpu_to_le16(node_size); - rc->mapping_count =3D cpu_to_le32(1); + rc->mapping_count =3D cpu_to_le32(map_blob->len); rc->mapping_offset =3D cpu_to_le32(sizeof(*rc)); =20 /* fully coherent device */ @@ -319,20 +375,23 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) rc->memory_properties.memory_flags =3D 0x3; /* CCA =3D CPM =3D DCAS = =3D 1 */ rc->pci_segment_number =3D 0; /* MCFG pci_segment */ =20 - /* Identity RID mapping covering the whole input RID range */ - idmap =3D &rc->id_mapping_array[0]; - idmap->input_base =3D 0; - idmap->id_count =3D cpu_to_le32(0xFFFF); - idmap->output_base =3D 0; + for (int i =3D 0; i < map_blob->len; i++) { + map =3D &g_array_index(map_blob, AcpiIortMapping, i); + idmap =3D &rc->id_mapping_array[i]; =20 - if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { - /* output IORT node is the smmuv3 node */ - idmap->output_reference =3D cpu_to_le32(smmu_offset); - } else { - /* output IORT node is the ITS group node (the first node) */ - idmap->output_reference =3D cpu_to_le32(iort_node_offset); + *idmap =3D map->idmap; + + if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3 && map->iommu) { + /* output IORT node is the smmuv3 node */ + idmap->output_reference =3D cpu_to_le32(smmu_offset); + } else { + /* output IORT node is the ITS group node (the first node) */ + idmap->output_reference =3D cpu_to_le32(iort_node_offset); + } } =20 + g_array_free(map_blob, true); + /* * Update the pointer address in case table_data->data moves during ab= ove * acpi_data_push operations. --=20 2.19.1