From nobody Mon Nov 25 02:55:09 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1719368317; cv=pass; d=zohomail.com; s=zohoarc; b=mdslSUbQcZLUr1tikhTQPzm6z4ltuC2KIaqJNkMNu4PAHlYOZRRabacpp7CJHpcn/IJOwxg2dpKPp6mPTjjVG0If/OXISKmWuRAXdsIqrfSpTSXuCLpUg9kgWLr/Sc1X73qPRK0v8iTqpn0o3OPIpYmhOjVKS+2b1Jv4qanSCr4= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1719368317; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=3JMy6Or3KW8qCfpz3EkC9MUSXl+ggzi3XZvt+LeIJ38=; b=GD1sMen7kmG2DYgif7zxOVDzTz9Z7NVSs0p3Jwl4gJI5zbgV6IDFMftk2CytSRvmOL7O+VI00wI5NNjNJX1BxXyl40gZ7ZSWdR+ZNaGu/cUnUm61XjE5LhKSFblnez8O5Fp7aQI/AL4r6ud1WKPMhUZUA9lyvOVG2jbtkYPIafY= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; 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; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1719368317464443.6083114680914; Tue, 25 Jun 2024 19:18:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sMI5N-0003pQ-0m; Tue, 25 Jun 2024 22:08:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sMI51-0003nI-C6 for qemu-devel@nongnu.org; Tue, 25 Jun 2024 22:08:18 -0400 Received: from mail-bn1nam02on20616.outbound.protection.outlook.com ([2a01:111:f403:2407::616] helo=NAM02-BN1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sMI4Q-0003fc-Dx for qemu-devel@nongnu.org; Tue, 25 Jun 2024 22:08:10 -0400 Received: from BN0PR08CA0023.namprd08.prod.outlook.com (2603:10b6:408:142::17) by LV3PR12MB9216.namprd12.prod.outlook.com (2603:10b6:408:1a5::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.30; Wed, 26 Jun 2024 00:29:32 +0000 Received: from BN3PEPF0000B077.namprd04.prod.outlook.com (2603:10b6:408:142:cafe::7c) by BN0PR08CA0023.outlook.office365.com (2603:10b6:408:142::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7719.22 via Frontend Transport; Wed, 26 Jun 2024 00:29:32 +0000 Received: from mail.nvidia.com (216.228.118.232) by BN3PEPF0000B077.mail.protection.outlook.com (10.167.243.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7677.15 via Frontend Transport; Wed, 26 Jun 2024 00:29:31 +0000 Received: from drhqmail201.nvidia.com (10.126.190.180) by mail.nvidia.com (10.127.129.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Tue, 25 Jun 2024 17:29:25 -0700 Received: from drhqmail203.nvidia.com (10.126.190.182) by drhqmail201.nvidia.com (10.126.190.180) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Tue, 25 Jun 2024 17:29:24 -0700 Received: from Asurada-Nvidia.nvidia.com (10.127.8.10) by mail.nvidia.com (10.126.190.182) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Tue, 25 Jun 2024 17:29:24 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=h9mz20+7Zc+3nDMJPq8YOF2kAb37d2iuqXdrXBPOlJ34CuWWSgG2mGlmjrVurLq/GGvIJJdpjP4LVmboT3qRD8MSlX6KwUK1Auqctf+WNSXmmp+8CZghVJ1LD1oNY7ZdWM+iuh6FLOvE+s1cXSm6EpI/bLhotKEeZHo0WbQ/+MdYi3rEHsusG4NCmvRhIYz8Yu5YgE92YUvaSL/+UoaxCkpHUvWKJ5iN8f/WoXQ4XiSMahJWRpHK+kOFdn8Sv/uZ3Ncd4RMyjGXw57Qm0Jp3b6LyXoYV98EWf4DrkE5NWPvY1KtR5vJ2dhMgmARiFn9FqOn9OwFhlOu2BkHGokFw+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3JMy6Or3KW8qCfpz3EkC9MUSXl+ggzi3XZvt+LeIJ38=; b=i6ysUjPO3E7dJD17VW8Z7eyKsVO/4XqVjw9cHr2G6FLf0h4w6AiJ2hAAPbxLVyEp9Efvt0ueVvK7gX438eWtWiAHB+foHDdGPEu1vT+E2p747S9S1ex4FTPXnte+LRTnNB4WoX0TM2h1VhQ5i5uM5N0ySu778vixFOI28EX/O/mdos/V6mjGXpnHY72Qt/6/exWdg/NocVM2RKoqDp+YqC31cWgPn2ZVbT+3A4NJjCo/l528uFfagQdLXyPV35EpO7ppshbTwnfUDGbvob/Si1mGZl4VNWWhQxJJTwkSTkHdxDuYXbaDThLIsCkkQtJhqRNDM4jIEGh7UxdEDWsbzQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.118.232) smtp.rcpttodomain=linaro.org smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=3JMy6Or3KW8qCfpz3EkC9MUSXl+ggzi3XZvt+LeIJ38=; b=s3Z7khQMR8T9G2v1ft9JqpNMQtnTKgnWwhmlMQhHUrUiqyvXvkifPsmYMwsHC74WaXEg5VEgK7Quvz8YzMRX/Dr9hAf51dnDkXZDufV7AHDh8TZzrdtNzOfg8Igtbk8obhtjmn+IIntpbYPLKP4yJe+3+MN9fx7PbpsQhWaRJwwtiTB85uQYlx2vLLH2tiZXDZqRziNnraS6cRKZ+4q042AcNy0IRctdYmz4Lzhlo6I7+BxNDnWlqk0TFmXkjwE5+cc9LNxhvhgEWN6+YbShCaBPcmGYJ28zrgXO1KiBotldJNSFVa72iind5pwyaRZsz8KUlXqdL2J78ii+vVWBjA== X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.118.232) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; 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 (protection.outlook.com: domain of nvidia.com designates 216.228.118.232 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.118.232; helo=mail.nvidia.com; pr=C From: Nicolin Chen To: , , , , , , CC: , , , , Subject: [PATCH RFCv1 01/10] hw/arm/virt-acpi-build: Add IORT RMR regions to handle MSI nested binding Date: Tue, 25 Jun 2024 17:28:28 -0700 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN3PEPF0000B077:EE_|LV3PR12MB9216:EE_ X-MS-Office365-Filtering-Correlation-Id: aa58b68c-3716-4f24-dbbb-08dc95770c44 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230038|36860700011|376012|7416012|1800799022|82310400024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?Z+UkL8PqjmL27JtixBriGNDW0AkCocb8MiF9RcGOwiLDdeamk+Im8/VB2RFb?= =?us-ascii?Q?r2B7ucowSA0czC3cgWF/HIzSkTQAIrYsgWtp9ebMfhlxQcYwrs3iJkiIApa5?= =?us-ascii?Q?1Zi+eOAGDUign46CbDrBuX/qo8URSXXsAOUJ1HOh+Yv89DO7oIizWLTTmZ+J?= =?us-ascii?Q?QrhxsMzE+4PJWBonEQF5F73bjv3z5gA+g46RBL9OWK2/ybEpjZV+YJ1Bm8gP?= =?us-ascii?Q?AXsilZ5EA0Qi+w/53fc10SACPfD95+c6tz63T/Z4IpRtiYvDhA57FStQIKX4?= =?us-ascii?Q?l409a+B/1BwQgkomp9VnCHqTWWyIdrgJkpdlkrhB4fi5ahIREty77vYEoWqB?= =?us-ascii?Q?rsW+Sa0x7v8ntZI7OExqvufkbpTwbvQ/qrp39wDV9shv8f8U1+RS18T7Fpq4?= =?us-ascii?Q?fnSSi04YXG96bije+IM9Kbr4QvtOYTfvKqPMko6CUio5mgnPE99ePBEWMvW8?= =?us-ascii?Q?QGcXxPAaLfW9UlwNRwFxkX0C/rnl7aoSnENz/Fu7Ra5RBpu9Vj8PpxaJX9QQ?= =?us-ascii?Q?FLSm7DOyxc4KTW/zlnHJETaglXwsclkEbj4EBlMQ2doy7zrNzuQAWCLmhr6d?= =?us-ascii?Q?kxFYsW6rozqBoKc9yJIAPnQj+XcUrB2MAfXaV5yH8zyfs036bYmNl44sVpcg?= =?us-ascii?Q?0qVQPM/gUKWLtZ8FJe62MwTY6hpfm8HIRNW90WuG7z7jXqHFBOQpxO6ATVqL?= =?us-ascii?Q?E9B9YRGeFsjOwlidQa/U0CJBEhq2lnBxfA6uR0P2fmYxVWFwMf5yy2V/3hvs?= =?us-ascii?Q?8QQlqh8UyFcOLWmiSQZP4lf1gXb6+QdjUfwaMwCtNZWU5QGjevgqGocJz8AI?= =?us-ascii?Q?UW6BBnUXa+hEZegmBGKJ8wXqMXzYaD1+8K47T8RJkpN9GsO1cG5h1tSsB7SV?= =?us-ascii?Q?xN3lILUF1jYeRpypk7a32v2rE9EB9SA5WBd4VCXClE0uFa0gncudBgZ7K3vO?= =?us-ascii?Q?eUic+faKdLNBakQYX8RKRnigvjaAlCj9K36+FsbN8jUXA1jXnfX3KJJybN9x?= =?us-ascii?Q?KT9P5JNi0ebDxr8RlpUWb2ZoG+z32ii+CQppQItH3DFAAkZkkoSFFERhRSb5?= =?us-ascii?Q?jQ/mhtdp/PVeFIoSjZH33hwwZ4fHqorc1rUAKhononsg9Eq6kUxhdHki2XWM?= =?us-ascii?Q?tfSGIMRJgcFE5xl+nYwJZtORjIfOwD829IlrJ4tWYN8SYZO2ngoWw8kH3SuY?= =?us-ascii?Q?SOVa/2/0HAD+bRnmOIiAuAO4Q29g0SCYHLSqCSccKgdvowfuIz+0fYVi3p3d?= =?us-ascii?Q?TBUL8X9Mp0+/c8+KDTaeeoZAYNwbyUyvwdTUTLaKDkifjt/UZDpsZ1kmfMNC?= =?us-ascii?Q?FcIMqkfn/WY8SRgHwmhgqoQ/yFor/TNMFM42USavParSBWtpNTncjoszYQj+?= =?us-ascii?Q?8nnJ3Lll8pHq/QjOWvB49rm3MVEn7+eNPheEhYMDtoYf4PWZOw=3D=3D?= X-Forefront-Antispam-Report: CIP:216.228.118.232; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc7edge1.nvidia.com; CAT:NONE; SFS:(13230038)(36860700011)(376012)(7416012)(1800799022)(82310400024); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jun 2024 00:29:31.7222 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: aa58b68c-3716-4f24-dbbb-08dc95770c44 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.118.232]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN3PEPF0000B077.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV3PR12MB9216 Received-SPF: softfail client-ip=2a01:111:f403:2407::616; envelope-from=nicolinc@nvidia.com; helo=NAM02-BN1-obe.outbound.protection.outlook.com X-Spam_score_int: -12 X-Spam_score: -1.3 X-Spam_bar: - X-Spam_report: (-1.3 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, KHOP_HELO_FCRDNS=0.4, T_SPF_TEMPERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1719368319315100003 Content-Type: text/plain; charset="utf-8" From: Eric Auger To handle SMMUv3 nested stage support it is practical to expose the guest with reserved memory regions (RMRs) covering the IOVAs used by the host kernel to map physical MSI doorbells. Those IOVAs belong to [0x8000000, 0x8100000] matching MSI_IOVA_BASE and MSI_IOVA_LENGTH definitions in kernel arm-smmu-v3 driver. This is the window used to allocate IOVAs matching physical MSI doorbells. With those RMRs, the guest is forced to use a flat mapping for this range. Hence the assigned device is programmed with one IOVA from this range. Stage 1, owned by the guest has a flat mapping for this IOVA. Stage2, owned by the VMM then enforces a mapping from this IOVA to the physical MSI doorbell. The creation of those RMR nodes only is relevant if nested stage SMMU is in use, along with VFIO. As VFIO devices can be hotplugged, all RMRs need to be created in advance. Hence the patch introduces a new arm virt "nested-smmuv3" iommu type. ARM DEN 0049E.b IORT specification also mandates that when RMRs are present, the OS must preserve PCIe configuration performed by the boot FW. So along with the RMR IORT nodes, a _DSM function #5, as defined by PCI FIRMWARE SPECIFICATION EVISION 3.3, chapter 4.6.5 is added to PCIe host bridge and PCIe expander bridge objects. Signed-off-by: Eric Auger Suggested-by: Jean-Philippe Brucker Signed-off-by: Nicolin Chen --- v2 -> v3: - Comply with IORT E.d spec. RMR node rev =3D 3; IORT rev =3D 5 With this spec revision, the restriction on number of Stream IDs that can be associated with memory ranges in an RMR node was removed. So no need anymore to define 1 RMR node per SID! --- hw/arm/virt-acpi-build.c | 84 +++++++++++++++++++++++++++++++++------- hw/arm/virt.c | 7 +++- include/hw/arm/virt.h | 7 ++++ 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 94363a6d65..d5e72800f6 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -132,6 +132,14 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMap= Entry *memmap, .bus =3D vms->bus, }; =20 + /* + * Nested SMMU requires RMRs for MSI 1-1 mapping, which + * require _DSM for PreservingPCI Boot Configurations + */ + if (vms->iommu =3D=3D VIRT_IOMMU_NESTED_SMMUV3) { + cfg.preserve_config =3D true; + } + if (vms->highmem_mmio) { cfg.mmio64 =3D memmap[VIRT_HIGH_PCIE_MMIO]; } @@ -216,16 +224,16 @@ static void acpi_dsdt_add_tpm(Aml *scope, VirtMachine= State *vms) * * Note that @id_count gets internally subtracted by one, following the sp= ec. */ -static void build_iort_id_mapping(GArray *table_data, uint32_t input_base, - uint32_t id_count, uint32_t out_ref) +static void +build_iort_id_mapping(GArray *table_data, uint32_t input_base, + uint32_t id_count, uint32_t out_ref, uint32_t flags) { build_append_int_noprefix(table_data, input_base, 4); /* Input base */ /* Number of IDs - The number of IDs in the range minus one */ build_append_int_noprefix(table_data, id_count - 1, 4); build_append_int_noprefix(table_data, input_base, 4); /* Output base */ build_append_int_noprefix(table_data, out_ref, 4); /* Output Reference= */ - /* Flags */ - build_append_int_noprefix(table_data, 0 /* Single mapping (disabled) *= /, 4); + build_append_int_noprefix(table_data, flags, 4); /* Flags */ } =20 struct AcpiIortIdMapping { @@ -267,6 +275,48 @@ static int iort_idmap_compare(gconstpointer a, gconstp= ointer b) return idmap_a->input_base - idmap_b->input_base; } =20 +static void +build_iort_rmr_nodes(GArray *table_data, GArray *smmu_idmaps, int smmu_off= set, uint32_t *id) { + AcpiIortIdMapping *range; + int i; + + for (i =3D 0; i < smmu_idmaps->len; i++) { + range =3D &g_array_index(smmu_idmaps, AcpiIortIdMapping, i); + int bdf =3D range->input_base; + + /* Table 18 Reserved Memory Range Node */ + + build_append_int_noprefix(table_data, 6 /* RMR */, 1); /* Type */ + /* Length */ + build_append_int_noprefix(table_data, 28 + ID_MAPPING_ENTRY_SIZE += 20, 2); + build_append_int_noprefix(table_data, 3, 1); /* Revision */ + build_append_int_noprefix(table_data, *id, 4); /* Identifier */ + /* Number of ID mappings */ + build_append_int_noprefix(table_data, 1, 4); + /* Reference to ID Array */ + build_append_int_noprefix(table_data, 28, 4); + + /* RMR specific data */ + + /* Flags */ + build_append_int_noprefix(table_data, 0 /* Disallow remapping */, = 4); + /* Number of Memory Range Descriptors */ + build_append_int_noprefix(table_data, 1 , 4); + /* Reference to Memory Range Descriptors */ + build_append_int_noprefix(table_data, 28 + ID_MAPPING_ENTRY_SIZE, = 4); + build_iort_id_mapping(table_data, bdf, range->id_count, smmu_offse= t, 1); + + /* Table 19 Memory Range Descriptor */ + + /* Physical Range offset */ + build_append_int_noprefix(table_data, 0x8000000, 8); + /* Physical Range length */ + build_append_int_noprefix(table_data, 0x100000, 8); + build_append_int_noprefix(table_data, 0, 4); /* Reserved */ + *id +=3D 1; + } +} + /* * Input Output Remapping Table (IORT) * Conforms to "IO Remapping Table System Software on ARM Platforms", @@ -282,17 +332,19 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) GArray *smmu_idmaps =3D g_array_new(false, true, sizeof(AcpiIortIdMapp= ing)); GArray *its_idmaps =3D g_array_new(false, true, sizeof(AcpiIortIdMappi= ng)); =20 - AcpiTable table =3D { .sig =3D "IORT", .rev =3D 3, .oem_id =3D vms->oe= m_id, + AcpiTable table =3D { .sig =3D "IORT", .rev =3D 5, .oem_id =3D vms->oe= m_id, .oem_table_id =3D vms->oem_table_id }; /* Table 2 The IORT */ acpi_table_begin(&table, table_data); =20 - if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { + if (virt_has_smmuv3(vms)) { AcpiIortIdMapping next_range =3D {0}; =20 object_child_foreach_recursive(object_get_root(), iort_host_bridges, smmu_idmaps); =20 + nb_nodes =3D 3; /* RC, ITS, SMMUv3 */ + /* Sort the smmu idmap by input_base */ g_array_sort(smmu_idmaps, iort_idmap_compare); =20 @@ -309,6 +361,9 @@ build_iort(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) } =20 next_range.input_base =3D idmap->input_base + idmap->id_count; + if (vms->iommu =3D=3D VIRT_IOMMU_NESTED_SMMUV3) { + nb_nodes++; + } } =20 /* Append the last RC -> ITS ID mapping */ @@ -317,7 +372,6 @@ build_iort(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) g_array_append_val(its_idmaps, next_range); } =20 - nb_nodes =3D 3; /* RC, ITS, SMMUv3 */ rc_mapping_count =3D smmu_idmaps->len + its_idmaps->len; } else { nb_nodes =3D 2; /* RC, ITS */ @@ -342,7 +396,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) /* GIC ITS Identifier Array */ build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4); =20 - if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { + if (virt_has_smmuv3(vms)) { int irq =3D vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE; =20 smmu_offset =3D table_data->len - table.table_offset; @@ -372,7 +426,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) build_append_int_noprefix(table_data, 0, 4); =20 /* output IORT node is the ITS group node (the first node) */ - build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET); + build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET, 0); } =20 /* Table 17 Root Complex Node */ @@ -405,7 +459,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) build_append_int_noprefix(table_data, 0, 3); /* Reserved */ =20 /* Output Reference */ - if (vms->iommu =3D=3D VIRT_IOMMU_SMMUV3) { + if (virt_has_smmuv3(vms)) { AcpiIortIdMapping *range; =20 /* translated RIDs connect to SMMUv3 node: RC -> SMMUv3 -> ITS */ @@ -413,7 +467,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) range =3D &g_array_index(smmu_idmaps, AcpiIortIdMapping, i); /* output IORT node is the smmuv3 node */ build_iort_id_mapping(table_data, range->input_base, - range->id_count, smmu_offset); + range->id_count, smmu_offset, 0); } =20 /* bypassed RIDs connect to ITS group node directly: RC -> ITS */ @@ -421,11 +475,15 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) range =3D &g_array_index(its_idmaps, AcpiIortIdMapping, i); /* output IORT node is the ITS group node (the first node) */ build_iort_id_mapping(table_data, range->input_base, - range->id_count, IORT_NODE_OFFSET); + range->id_count, IORT_NODE_OFFSET, 0); } } else { /* output IORT node is the ITS group node (the first node) */ - build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET); + build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET, 0); + } + + if (vms->iommu =3D=3D VIRT_IOMMU_NESTED_SMMUV3) { + build_iort_rmr_nodes(table_data, smmu_idmaps, smmu_offset, &id); } =20 acpi_table_end(linker, &table); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 3c93c0c0a6..78af2d2195 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1396,7 +1396,7 @@ static void create_smmu(const VirtMachineState *vms, DeviceState *dev; MachineState *ms =3D MACHINE(vms); =20 - if (vms->iommu !=3D VIRT_IOMMU_SMMUV3 || !vms->iommu_phandle) { + if (!virt_has_smmuv3(vms) || !vms->iommu_phandle) { return; } =20 @@ -1578,6 +1578,7 @@ static void create_pcie(VirtMachineState *vms) =20 switch (vms->iommu) { case VIRT_IOMMU_SMMUV3: + case VIRT_IOMMU_NESTED_SMMUV3: create_smmu(vms, vms->bus); qemu_fdt_setprop_cells(ms->fdt, nodename, "iommu-map", 0x0, vms->iommu_phandle, 0x0, 0x10000); @@ -2653,6 +2654,8 @@ static char *virt_get_iommu(Object *obj, Error **errp) return g_strdup("none"); case VIRT_IOMMU_SMMUV3: return g_strdup("smmuv3"); + case VIRT_IOMMU_NESTED_SMMUV3: + return g_strdup("nested-smmuv3"); default: g_assert_not_reached(); } @@ -2664,6 +2667,8 @@ static void virt_set_iommu(Object *obj, const char *v= alue, Error **errp) =20 if (!strcmp(value, "smmuv3")) { vms->iommu =3D VIRT_IOMMU_SMMUV3; + } else if (!strcmp(value, "nested-smmuv3")) { + vms->iommu =3D VIRT_IOMMU_NESTED_SMMUV3; } else if (!strcmp(value, "none")) { vms->iommu =3D VIRT_IOMMU_NONE; } else { diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index bb486d36b1..7df0813e28 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -89,6 +89,7 @@ enum { typedef enum VirtIOMMUType { VIRT_IOMMU_NONE, VIRT_IOMMU_SMMUV3, + VIRT_IOMMU_NESTED_SMMUV3, VIRT_IOMMU_VIRTIO, } VirtIOMMUType; =20 @@ -209,4 +210,10 @@ static inline int virt_gicv3_redist_region_count(VirtM= achineState *vms) vms->highmem_redists) ? 2 : 1; } =20 +static inline bool virt_has_smmuv3(const VirtMachineState *vms) +{ + return vms->iommu =3D=3D VIRT_IOMMU_SMMUV3 || + vms->iommu =3D=3D VIRT_IOMMU_NESTED_SMMUV3; +} + #endif /* QEMU_ARM_VIRT_H */ --=20 2.43.0