From nobody Sun Nov 2 12:45:39 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass header.i=teddy.astie@vates.tech; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1739787528; cv=none; d=zohomail.com; s=zohoarc; b=mDvry/hDzMThh5JtBe3cKELEQc5E7lDfE4niKxpg/QEJMMg7l3BLIokC8Gswb+IjxbCpxUyLbPKccy6xM3zpYR44ryJiNj1h3Z3rNIMqXo6h/j0O2P+ItOE9Lz+0bcxeCtoKiXRmHBYgjke3fejbpWxISXkZ+ftIY6Rg+mNXuNc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1739787528; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=JKPPS3Q607//7imzk+rG+e9sgZlVye70tpXwjS+krKI=; b=jsffBUvnu4SE/fUyXqGE9O8e/lWfTApEq6yNeF8J0Ql9kXUzVuqv6pKDSl4u3SRTZeq4pbo1xtKryZNuddv0RwzGgCOC1n/H5f+Wie2yY2ueu+k3oe44BWUnp036hgyFVynYl6KUsfpEFxITY56bEC+s5e49lZ7anbmzO15Kapo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=teddy.astie@vates.tech; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1739787528949513.4268461213179; Mon, 17 Feb 2025 02:18:48 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.890005.1299065 (Exim 4.92) (envelope-from ) id 1tjyCo-0000sf-Te; Mon, 17 Feb 2025 10:18:26 +0000 Received: by outflank-mailman (output) from mailman id 890005.1299065; Mon, 17 Feb 2025 10:18:26 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tjyCo-0000rM-Ob; Mon, 17 Feb 2025 10:18:26 +0000 Received: by outflank-mailman (input) for mailman id 890005; Mon, 17 Feb 2025 10:18:25 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tjyCn-0007sm-A0 for xen-devel@lists.xenproject.org; Mon, 17 Feb 2025 10:18:25 +0000 Received: from mail13.wdc04.mandrillapp.com (mail13.wdc04.mandrillapp.com [205.201.139.13]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 83cc45cc-ed18-11ef-9896-31a8f345e629; Mon, 17 Feb 2025 11:18:22 +0100 (CET) Received: from pmta16.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail13.wdc04.mandrillapp.com (Mailchimp) with ESMTP id 4YxJWx6zvBzNCd9LM for ; Mon, 17 Feb 2025 10:18:21 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 86b6fa1377c544e19369cdbc272e29ad; Mon, 17 Feb 2025 10:18:21 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 83cc45cc-ed18-11ef-9896-31a8f345e629 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1739787502; x=1740057502; bh=JKPPS3Q607//7imzk+rG+e9sgZlVye70tpXwjS+krKI=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=bAQIiWz6v01F5RaPZocRDCKJMvWMTDX71rdUYH4L1bPCNR5TUnWOWi/MhhF5KqJqp 9K+NWAM08/+onhvgFW0y50Ac/i7CpbOW1exz+8kJpwOYsyUEuC5QTF+hWUOm62DuzD IKW7pFNwbL6RVkf4dsIVImu4d/FDAnHfIt0LBen46+bsgviH6Z2y2xoke3415e3Jk5 5B9UyJkKqJ91GzS8qmApV+/FzT5kcmXn89xVfXc4zugJ/WGmAkBapqHyOeRsbdn/A6 uJmVYB3cxtVoiDqa60Qsup+xfkkCoDIpDPmKFpLzGwQLJTLV3rxZLQOCdTbinfcXGB gJeudrVBNSQ0A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1739787502; x=1740048002; i=teddy.astie@vates.tech; bh=JKPPS3Q607//7imzk+rG+e9sgZlVye70tpXwjS+krKI=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=eYU+h8+hnuO3ICTeFUBLABVGweIxZwNFQeUUD9l066kubqB5bE6VI5L5FgyP+AeWh iHNPcvjkmSm4+0TXw/9ZMyLGKTGf3/bhqi9RP3s+XMx3q7zRoO+T2z9ZRmLkGQLqp0 Yh3X7kmdCzuqRPzDg9MvaQlassqBYicOS2AfHNiSXOJMyYQfBmLaitJguyOH842yQ7 sr1rQkomAEPNwX6ru+jiK0G1ureeraeJvh0GU08bsBPmYiVi67zNskni6ap62bSlIb pNzeDAxs9LgTiqFlVTRy/oTFNtcum+0BL1QjxPARHVvt3psW5VIj8JKSqlUwpRdCLh 3PXowsgd99XLA== From: "Teddy Astie" Subject: =?utf-8?Q?[XEN=20RFC=20PATCH=20v6=2005/11]=20iommu:=20Simplify=20quarantine=20logic?= X-Mailer: git-send-email 2.47.2 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1739787500867 To: xen-devel@lists.xenproject.org Cc: "Teddy Astie" , "Jan Beulich" , "Andrew Cooper" , "=?utf-8?Q?Roger=20Pau=20Monn=C3=A9?=" Message-Id: <7ccad8409ffdfc026f86303729f3f45efd9bae3e.1739785339.git.teddy.astie@vates.tech> In-Reply-To: References: X-Native-Encoded: 1 X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.86b6fa1377c544e19369cdbc272e29ad?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250217:md Date: Mon, 17 Feb 2025 10:18:21 +0000 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity teddy.astie@vates.tech) (identity @mandrillapp.com) X-ZM-MESSAGEID: 1739787531569019100 Content-Type: text/plain; charset="utf-8" Current quarantine code is very hard to change and is very complicated, remove most bits of it and replace it with direct reassignement to dom_io domain instead. Signed-off-by: Teddy Astie --- A idea would be to rework this feature using the new reworked IOMMU subsystem. --- xen/arch/x86/include/asm/pci.h | 17 -- xen/drivers/passthrough/amd/iommu_map.c | 129 +--------- xen/drivers/passthrough/amd/pci_amd_iommu.c | 51 +--- xen/drivers/passthrough/pci.c | 7 +- xen/drivers/passthrough/vtd/iommu.c | 253 ++------------------ xen/drivers/passthrough/x86/iommu.c | 1 - 6 files changed, 29 insertions(+), 429 deletions(-) diff --git a/xen/arch/x86/include/asm/pci.h b/xen/arch/x86/include/asm/pci.h index fd5480d67d..214c1a0948 100644 --- a/xen/arch/x86/include/asm/pci.h +++ b/xen/arch/x86/include/asm/pci.h @@ -15,23 +15,6 @@ =20 struct arch_pci_dev { vmask_t used_vectors; - /* - * These fields are (de)initialized under pcidevs-lock. Other uses of - * them don't race (de)initialization and hence don't strictly need any - * locking. - */ - union { - /* Subset of struct arch_iommu's fields, to be used in dom_io. */ - struct { - uint64_t pgd_maddr; - } vtd; - struct { - struct page_info *root_table; - } amd; - }; - domid_t pseudo_domid; - mfn_t leaf_mfn; - struct page_list_head pgtables_list; }; =20 int pci_conf_write_intercept(unsigned int seg, unsigned int bdf, diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthro= ugh/amd/iommu_map.c index 7514384789..91d8c21048 100644 --- a/xen/drivers/passthrough/amd/iommu_map.c +++ b/xen/drivers/passthrough/amd/iommu_map.c @@ -656,9 +656,6 @@ int amd_iommu_reserve_domain_unity_map(struct domain *d= , struct iommu_context *c { int rc; =20 - if ( d =3D=3D dom_io ) - return 0; - for ( rc =3D 0; !rc && map; map =3D map->next ) { p2m_access_t p2ma =3D p2m_access_n; @@ -680,9 +677,6 @@ int amd_iommu_reserve_domain_unity_unmap(struct domain = *d, struct iommu_context { int rc; =20 - if ( d =3D=3D dom_io ) - return 0; - for ( rc =3D 0; map; map =3D map->next ) { int ret =3D iommu_identity_mapping(d, ctx, p2m_access_x, map->addr, @@ -771,134 +765,15 @@ int cf_check amd_iommu_get_reserved_device_memory( return 0; } =20 -static int fill_qpt(union amd_iommu_pte *this, unsigned int level, - struct page_info *pgs[IOMMU_MAX_PT_LEVELS]) -{ - struct domain_iommu *hd =3D dom_iommu(dom_io); - struct iommu_context *ctx =3D iommu_default_context(dom_io); - unsigned int i; - int rc =3D 0; - - for ( i =3D 0; !rc && i < PTE_PER_TABLE_SIZE; ++i ) - { - union amd_iommu_pte *pte =3D &this[i], *next; - - if ( !pte->pr ) - { - if ( !pgs[level] ) - { - /* - * The pgtable allocator is fine for the leaf page, as wel= l as - * page table pages, and the resulting allocations are alw= ays - * zeroed. - */ - pgs[level] =3D iommu_alloc_pgtable(hd, ctx, 0); - if ( !pgs[level] ) - { - rc =3D -ENOMEM; - break; - } - - if ( level ) - { - next =3D __map_domain_page(pgs[level]); - rc =3D fill_qpt(next, level - 1, pgs); - unmap_domain_page(next); - } - } - - /* - * PDEs are essentially a subset of PTEs, so this function - * is fine to use even at the leaf. - */ - set_iommu_pde_present(pte, mfn_x(page_to_mfn(pgs[level])), lev= el, - true, true); - } - else if ( level && pte->next_level ) - { - next =3D map_domain_page(_mfn(pte->mfn)); - rc =3D fill_qpt(next, level - 1, pgs); - unmap_domain_page(next); - } - } - - return rc; -} - int cf_check amd_iommu_quarantine_init(struct pci_dev *pdev, bool scratch_= page) { - struct domain_iommu *hd =3D dom_iommu(dom_io); - struct iommu_context *ctx =3D iommu_default_context(dom_io); - unsigned int level =3D ctx->arch.amd.paging_mode; - unsigned int req_id =3D get_dma_requestor_id(pdev->seg, pdev->sbdf.bdf= ); - const struct ivrs_mappings *ivrs_mappings =3D get_ivrs_mappings(pdev->= seg); - int rc; + amd_iommu_quarantine_teardown(pdev); =20 - ASSERT(pcidevs_locked()); - ASSERT(!ctx->arch.amd.root_table); - ASSERT(page_list_empty(&ctx->arch.pgtables)); - - if ( !scratch_page && !ivrs_mappings[req_id].unity_map ) - return 0; - - ASSERT(pdev->arch.pseudo_domid !=3D DOMID_INVALID); - - if ( pdev->arch.amd.root_table ) - { - clear_domain_page(pdev->arch.leaf_mfn); - return 0; - } - - pdev->arch.amd.root_table =3D iommu_alloc_pgtable(hd, ctx, 0); - if ( !pdev->arch.amd.root_table ) - return -ENOMEM; - - /* Transiently install the root into DomIO, for iommu_identity_mapping= (). */ - ctx->arch.amd.root_table =3D pdev->arch.amd.root_table; - - rc =3D amd_iommu_reserve_domain_unity_map(dom_io, ctx, - ivrs_mappings[req_id].unity_ma= p, - 0); - - iommu_identity_map_teardown(dom_io, ctx); - ctx->arch.amd.root_table =3D NULL; - - if ( rc ) - AMD_IOMMU_WARN("%pp: quarantine unity mapping failed\n", &pdev->sb= df); - else if ( scratch_page ) - { - union amd_iommu_pte *root; - struct page_info *pgs[IOMMU_MAX_PT_LEVELS] =3D {}; - - root =3D __map_domain_page(pdev->arch.amd.root_table); - rc =3D fill_qpt(root, level - 1, pgs); - unmap_domain_page(root); - - pdev->arch.leaf_mfn =3D page_to_mfn(pgs[0]); - } - - page_list_move(&pdev->arch.pgtables_list, &ctx->arch.pgtables); - - if ( rc ) - amd_iommu_quarantine_teardown(pdev); - - return rc; + return 0; } =20 void amd_iommu_quarantine_teardown(struct pci_dev *pdev) { - struct iommu_context *ctx =3D iommu_default_context(dom_io); - - ASSERT(pcidevs_locked()); - - if ( !pdev->arch.amd.root_table ) - return; - - ASSERT(page_list_empty(&ctx->arch.pgtables)); - page_list_move(&ctx->arch.pgtables, &pdev->arch.pgtables_list); - while ( iommu_free_pgtables(dom_io, ctx) =3D=3D -ERESTART ) - /* nothing */; - pdev->arch.amd.root_table =3D NULL; } =20 /* diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/pass= through/amd/pci_amd_iommu.c index a3815d71be..0008b35162 100644 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c @@ -138,9 +138,6 @@ static int __must_check amd_iommu_setup_domain_device( const struct page_info *root_pg; domid_t domid; =20 - if ( QUARANTINE_SKIP(domain, pdev) ) - return 0; - BUG_ON(!ctx->arch.amd.paging_mode || !iommu->dev_table.buffer); =20 rc =3D allocate_domain_resources(domain); @@ -159,16 +156,8 @@ static int __must_check amd_iommu_setup_domain_device( dte =3D &table[req_id]; ivrs_dev =3D &get_ivrs_mappings(iommu->seg)[req_id]; =20 - if ( domain !=3D dom_io ) - { - root_pg =3D ctx->arch.amd.root_table; - domid =3D domain->domain_id; - } - else - { - root_pg =3D pdev->arch.amd.root_table; - domid =3D pdev->arch.pseudo_domid; - } + root_pg =3D ctx->arch.amd.root_table; + domid =3D domain->domain_id; =20 spin_lock_irqsave(&iommu->lock, flags); =20 @@ -414,9 +403,6 @@ static void amd_iommu_disable_domain_device(const struc= t domain *domain, int req_id; u8 bus =3D pdev->bus; =20 - if ( QUARANTINE_SKIP(domain, pdev) ) - return; - ASSERT(pcidevs_locked()); =20 if ( pci_ats_device(iommu->seg, bus, pdev->devfn) && @@ -479,14 +465,9 @@ static int cf_check reassign_device( return -ENODEV; } =20 - if ( !QUARANTINE_SKIP(target, pdev) ) - { - rc =3D amd_iommu_setup_domain_device(target, target_ctx, iommu, de= vfn, pdev); - if ( rc ) - return rc; - } - else - amd_iommu_disable_domain_device(source, iommu, devfn, pdev); + rc =3D amd_iommu_setup_domain_device(target, target_ctx, iommu, devfn,= pdev); + if ( rc ) + return rc; =20 if ( devfn =3D=3D pdev->devfn && pdev->domain !=3D target ) { @@ -579,8 +560,6 @@ static int cf_check amd_iommu_add_device(u8 devfn, stru= ct pci_dev *pdev) struct iommu_context *ctx; u16 bdf; struct ivrs_mappings *ivrs_mappings; - bool fresh_domid =3D false; - int ret; =20 if ( !pdev->domain ) return -EINVAL; @@ -649,22 +628,7 @@ static int cf_check amd_iommu_add_device(u8 devfn, str= uct pci_dev *pdev) AMD_IOMMU_WARN("%pd: unity mapping failed for %pp\n", pdev->domain, &PCI_SBDF(pdev->seg, bdf)); =20 - if ( iommu_quarantine && pdev->arch.pseudo_domid =3D=3D DOMID_INVALID ) - { - pdev->arch.pseudo_domid =3D iommu_alloc_domid(iommu->domid_map); - if ( pdev->arch.pseudo_domid =3D=3D DOMID_INVALID ) - return -ENOSPC; - fresh_domid =3D true; - } - - ret =3D amd_iommu_setup_domain_device(pdev->domain, ctx, iommu, devfn,= pdev); - if ( ret && fresh_domid ) - { - iommu_free_domid(pdev->arch.pseudo_domid, iommu->domid_map); - pdev->arch.pseudo_domid =3D DOMID_INVALID; - } - - return ret; + return amd_iommu_setup_domain_device(pdev->domain, ctx, iommu, devfn, = pdev); } =20 static int cf_check amd_iommu_remove_device(u8 devfn, struct pci_dev *pdev) @@ -700,9 +664,6 @@ static int cf_check amd_iommu_remove_device(u8 devfn, s= truct pci_dev *pdev) =20 amd_iommu_quarantine_teardown(pdev); =20 - iommu_free_domid(pdev->arch.pseudo_domid, iommu->domid_map); - pdev->arch.pseudo_domid =3D DOMID_INVALID; - if ( amd_iommu_perdev_intremap && ivrs_mappings[bdf].dte_requestor_id =3D=3D bdf && ivrs_mappings[bdf].intremap_table ) diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 777c6b1a7f..e1ca74b477 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -1370,12 +1370,7 @@ static int cf_check _dump_pci_devices(struct pci_seg= *pseg, void *arg) list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list ) { printk("%pp - ", &pdev->sbdf); -#ifdef CONFIG_X86 - if ( pdev->domain =3D=3D dom_io ) - printk("DomIO:%x", pdev->arch.pseudo_domid); - else -#endif - printk("%pd", pdev->domain); + printk("%pd", pdev->domain); printk(" - node %-3d", (pdev->node !=3D NUMA_NO_NODE) ? pdev->node= : -1); pdev_dump_msi(pdev); printk("\n"); diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/= vtd/iommu.c index f60f39ee1d..55562084fc 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -49,14 +49,6 @@ #define CONTIG_MASK DMA_PTE_CONTIG_MASK #include =20 -/* dom_io is used as a sentinel for quarantined devices */ -#define QUARANTINE_SKIP(d, pgd_maddr) ((d) =3D=3D dom_io && !(pgd_maddr)) -#define DEVICE_DOMID(d, pdev) ((d) !=3D dom_io ? (d)->domain_id \ - : (pdev)->arch.pseudo_domid) -#define DEVICE_PGTABLE(d, pdev) ((d) !=3D dom_io \ - ? iommu_default_context(d)->arch.vtd.pgd_= maddr \ - : (pdev)->arch.vtd.pgd_maddr) - bool __read_mostly iommu_igfx =3D true; bool __read_mostly iommu_qinval =3D true; #ifndef iommu_snoop @@ -1494,8 +1486,6 @@ int domain_context_mapping_one( int rc, ret; bool flush_dev_iotlb; =20 - if ( QUARANTINE_SKIP(domain, pgd_maddr) ) - return 0; =20 ASSERT(pcidevs_locked()); spin_lock(&iommu->lock); @@ -1512,8 +1502,6 @@ int domain_context_mapping_one( domid =3D did_to_domain_id(iommu, prev_did); if ( domid < DOMID_FIRST_RESERVED ) prev_dom =3D rcu_lock_domain_by_id(domid); - else if ( pdev ? domid =3D=3D pdev->arch.pseudo_domid : domid > DO= MID_MASK ) - prev_dom =3D rcu_lock_domain(dom_io); if ( !prev_dom ) { spin_unlock(&iommu->lock); @@ -1645,8 +1633,8 @@ int domain_context_mapping_one( ret =3D domain_context_unmap_one(domain, iommu, bus, devfn); else ret =3D domain_context_mapping_one(prev_dom, ctx, iommu, bus, = devfn, pdev, - DEVICE_DOMID(prev_dom, pdev), - DEVICE_PGTABLE(prev_dom, pdev= ), + prev_dom->domain_id, + iommu_default_context(prev_do= m)->arch.vtd.pgd_maddr, (mode & MAP_WITH_RMRR) | MAP_ERROR_RECOVERY) < 0; =20 @@ -1668,8 +1656,8 @@ static int domain_context_mapping(struct domain *doma= in, struct iommu_context *c { const struct acpi_drhd_unit *drhd =3D acpi_find_matched_drhd_unit(pdev= ); const struct acpi_rmrr_unit *rmrr; - paddr_t pgd_maddr =3D DEVICE_PGTABLE(domain, pdev); - domid_t orig_domid =3D pdev->arch.pseudo_domid; + paddr_t pgd_maddr =3D ctx->arch.vtd.pgd_maddr; + domid_t did =3D domain->domain_id; int ret =3D 0; unsigned int i, mode =3D 0; uint16_t seg =3D pdev->seg, bdf; @@ -1722,20 +1710,11 @@ static int domain_context_mapping(struct domain *do= main, struct iommu_context *c if ( !drhd ) return -ENODEV; =20 - if ( iommu_quarantine && orig_domid =3D=3D DOMID_INVALID ) - { - pdev->arch.pseudo_domid =3D - iommu_alloc_domid(drhd->iommu->pseudo_domid_map); - if ( pdev->arch.pseudo_domid =3D=3D DOMID_INVALID ) - return -ENOSPC; - } - if ( iommu_debug ) printk(VTDPREFIX "%pd:PCIe: map %pp\n", domain, &PCI_SBDF(seg, bus, devfn)); ret =3D domain_context_mapping_one(domain, ctx, drhd->iommu, bus, = devfn, pdev, - DEVICE_DOMID(domain, pdev), pgd_m= addr, - mode); + did, pgd_maddr, mode); if ( ret > 0 ) ret =3D 0; if ( !ret && devfn =3D=3D pdev->devfn && ats_device(pdev, drhd) > = 0 ) @@ -1747,21 +1726,12 @@ static int domain_context_mapping(struct domain *do= main, struct iommu_context *c if ( !drhd ) return -ENODEV; =20 - if ( iommu_quarantine && orig_domid =3D=3D DOMID_INVALID ) - { - pdev->arch.pseudo_domid =3D - iommu_alloc_domid(drhd->iommu->pseudo_domid_map); - if ( pdev->arch.pseudo_domid =3D=3D DOMID_INVALID ) - return -ENOSPC; - } - if ( iommu_debug ) printk(VTDPREFIX "%pd:PCI: map %pp\n", domain, &PCI_SBDF(seg, bus, devfn)); =20 ret =3D domain_context_mapping_one(domain, ctx, drhd->iommu, bus, = devfn, - pdev, DEVICE_DOMID(domain, pdev), - pgd_maddr, mode); + pdev, did, pgd_maddr, mode); if ( ret < 0 ) break; prev_present =3D ret; @@ -1791,8 +1761,7 @@ static int domain_context_mapping(struct domain *doma= in, struct iommu_context *c */ if ( ret >=3D 0 ) ret =3D domain_context_mapping_one(domain, ctx, drhd->iommu, b= us, devfn, - NULL, DEVICE_DOMID(domain, pd= ev), - pgd_maddr, mode); + NULL, did, pgd_maddr, mode); =20 /* * Devices behind PCIe-to-PCI/PCIx bridge may generate different @@ -1807,8 +1776,7 @@ static int domain_context_mapping(struct domain *doma= in, struct iommu_context *c if ( !ret && pdev_type(seg, bus, devfn) =3D=3D DEV_TYPE_PCIe2PCI_B= RIDGE && (secbus !=3D pdev->bus || pdev->devfn !=3D 0) ) ret =3D domain_context_mapping_one(domain, ctx, drhd->iommu, s= ecbus, 0, - NULL, DEVICE_DOMID(domain, pd= ev), - pgd_maddr, mode); + NULL, did, pgd_maddr, mode); =20 if ( ret ) { @@ -1830,13 +1798,6 @@ static int domain_context_mapping(struct domain *dom= ain, struct iommu_context *c if ( !ret && devfn =3D=3D pdev->devfn ) pci_vtd_quirk(pdev); =20 - if ( ret && drhd && orig_domid =3D=3D DOMID_INVALID ) - { - iommu_free_domid(pdev->arch.pseudo_domid, - drhd->iommu->pseudo_domid_map); - pdev->arch.pseudo_domid =3D DOMID_INVALID; - } - return ret; } =20 @@ -1994,10 +1955,6 @@ static const struct acpi_drhd_unit *domain_context_u= nmap( return ERR_PTR(-EINVAL); } =20 - if ( !ret && pdev->devfn =3D=3D devfn && - !QUARANTINE_SKIP(domain, pdev->arch.vtd.pgd_maddr) ) - check_cleanup_domid_map(domain, pdev, iommu); - return drhd; } =20 @@ -2031,21 +1988,6 @@ static void cf_check iommu_domain_teardown(struct do= main *d) static void quarantine_teardown(struct pci_dev *pdev, const struct acpi_drhd_unit *drhd) { - struct iommu_context *ctx =3D iommu_default_context(dom_io); - - ASSERT(pcidevs_locked()); - - if ( !pdev->arch.vtd.pgd_maddr ) - return; - - ASSERT(page_list_empty(&ctx->arch.pgtables)); - page_list_move(&ctx->arch.pgtables, &pdev->arch.pgtables_list); - while ( iommu_free_pgtables(dom_io, ctx) =3D=3D -ERESTART ) - /* nothing */; - pdev->arch.vtd.pgd_maddr =3D 0; - - if ( drhd ) - cleanup_domid_map(pdev->arch.pseudo_domid, drhd->iommu); } =20 static int __must_check cf_check intel_iommu_map_page( @@ -2386,13 +2328,6 @@ static int cf_check intel_iommu_remove_device(u8 dev= fn, struct pci_dev *pdev) =20 quarantine_teardown(pdev, drhd); =20 - if ( drhd ) - { - iommu_free_domid(pdev->arch.pseudo_domid, - drhd->iommu->pseudo_domid_map); - pdev->arch.pseudo_domid =3D DOMID_INVALID; - } - return 0; } =20 @@ -2750,42 +2685,22 @@ static int cf_check reassign_device_ownership( { int ret; =20 - if ( !QUARANTINE_SKIP(target, pdev->arch.vtd.pgd_maddr) ) - { - struct iommu_context *target_ctx =3D iommu_default_context(target); - - if ( !has_arch_pdevs(target) ) - vmx_pi_hooks_assign(target); + if ( !has_arch_pdevs(target) ) + vmx_pi_hooks_assign(target); =20 #ifdef CONFIG_PV - /* - * Devices assigned to untrusted domains (here assumed to be any d= omU) - * can attempt to send arbitrary LAPIC/MSI messages. We are unprot= ected - * by the root complex unless interrupt remapping is enabled. - */ - if ( !iommu_intremap && !is_hardware_domain(target) && - !is_system_domain(target) ) - untrusted_msi =3D true; + /* + * Devices assigned to untrusted domains (here assumed to be any do= mU) + * can attempt to send arbitrary LAPIC/MSI messages. We are unprote= cted + * by the root complex unless interrupt remapping is enabled. + */ + if ( !iommu_intremap && !is_hardware_domain(target) && + !is_system_domain(target) ) + untrusted_msi =3D true; #endif =20 - ret =3D domain_context_mapping(target, target_ctx, devfn, pdev); - - if ( !ret && pdev->devfn =3D=3D devfn && - !QUARANTINE_SKIP(source, pdev->arch.vtd.pgd_maddr) ) - { - const struct acpi_drhd_unit *drhd =3D acpi_find_matched_drhd_u= nit(pdev); + ret =3D domain_context_mapping(target, iommu_default_context(target), = devfn, pdev); =20 - if ( drhd ) - check_cleanup_domid_map(source, pdev, drhd->iommu); - } - } - else - { - const struct acpi_drhd_unit *drhd; - - drhd =3D domain_context_unmap(source, devfn, pdev); - ret =3D IS_ERR(drhd) ? PTR_ERR(drhd) : 0; - } if ( ret ) { if ( !has_arch_pdevs(target) ) @@ -2884,9 +2799,6 @@ static int cf_check intel_iommu_assign_device( } } =20 - if ( d =3D=3D dom_io ) - return reassign_device_ownership(s, d, devfn, pdev); - /* Setup rmrr identity mapping */ for_each_rmrr_device( rmrr, bdf, i ) { @@ -3096,135 +3008,10 @@ static void cf_check vtd_dump_page_tables(struct d= omain *d) agaw_to_level(hd->arch.vtd.agaw), 0, 0); } =20 -static int fill_qpt(struct dma_pte *this, unsigned int level, - struct page_info *pgs[6]) -{ - struct domain_iommu *hd =3D dom_iommu(dom_io); - struct iommu_context *ctx =3D iommu_default_context(dom_io); - unsigned int i; - int rc =3D 0; - - for ( i =3D 0; !rc && i < PTE_NUM; ++i ) - { - struct dma_pte *pte =3D &this[i], *next; - - if ( !dma_pte_present(*pte) ) - { - if ( !pgs[level] ) - { - /* - * The pgtable allocator is fine for the leaf page, as wel= l as - * page table pages, and the resulting allocations are alw= ays - * zeroed. - */ - pgs[level] =3D iommu_alloc_pgtable(hd, ctx, 0); - if ( !pgs[level] ) - { - rc =3D -ENOMEM; - break; - } - - if ( level ) - { - next =3D map_vtd_domain_page(page_to_maddr(pgs[level])= ); - rc =3D fill_qpt(next, level - 1, pgs); - unmap_vtd_domain_page(next); - } - } - - dma_set_pte_addr(*pte, page_to_maddr(pgs[level])); - dma_set_pte_readable(*pte); - dma_set_pte_writable(*pte); - } - else if ( level && !dma_pte_superpage(*pte) ) - { - next =3D map_vtd_domain_page(dma_pte_addr(*pte)); - rc =3D fill_qpt(next, level - 1, pgs); - unmap_vtd_domain_page(next); - } - } - - return rc; -} - static int cf_check intel_iommu_quarantine_init(struct pci_dev *pdev, bool scratch_page) { - struct domain_iommu *hd =3D dom_iommu(dom_io); - struct iommu_context *ctx =3D iommu_default_context(dom_io); - struct page_info *pg; - unsigned int agaw =3D hd->arch.vtd.agaw; - unsigned int level =3D agaw_to_level(agaw); - const struct acpi_drhd_unit *drhd; - const struct acpi_rmrr_unit *rmrr; - unsigned int i, bdf; - bool rmrr_found =3D false; - int rc; - - ASSERT(pcidevs_locked()); - ASSERT(!ctx->arch.vtd.pgd_maddr); - ASSERT(page_list_empty(&ctx->arch.pgtables)); - - if ( pdev->arch.vtd.pgd_maddr ) - { - clear_domain_page(pdev->arch.leaf_mfn); - return 0; - } - - drhd =3D acpi_find_matched_drhd_unit(pdev); - if ( !drhd ) - return -ENODEV; - - pg =3D iommu_alloc_pgtable(hd, ctx, 0); - if ( !pg ) - return -ENOMEM; - - rc =3D context_set_domain_id(NULL, pdev->arch.pseudo_domid, drhd->iomm= u); - - /* Transiently install the root into DomIO, for iommu_identity_mapping= (). */ - ctx->arch.vtd.pgd_maddr =3D page_to_maddr(pg); - - for_each_rmrr_device ( rmrr, bdf, i ) - { - if ( rc ) - break; - - if ( rmrr->segment =3D=3D pdev->seg && bdf =3D=3D pdev->sbdf.bdf ) - { - rmrr_found =3D true; - - rc =3D iommu_identity_mapping(dom_io, ctx, p2m_access_rw, - rmrr->base_address, rmrr->end_addr= ess, - 0); - if ( rc ) - printk(XENLOG_ERR VTDPREFIX - "%pp: RMRR quarantine mapping failed\n", - &pdev->sbdf); - } - } - - iommu_identity_map_teardown(dom_io, ctx); - ctx->arch.vtd.pgd_maddr =3D 0; - pdev->arch.vtd.pgd_maddr =3D page_to_maddr(pg); - - if ( !rc && scratch_page ) - { - struct dma_pte *root; - struct page_info *pgs[6] =3D {}; - - root =3D map_vtd_domain_page(pdev->arch.vtd.pgd_maddr); - rc =3D fill_qpt(root, level - 1, pgs); - unmap_vtd_domain_page(root); - - pdev->arch.leaf_mfn =3D page_to_mfn(pgs[0]); - } - - page_list_move(&pdev->arch.pgtables_list, &ctx->arch.pgtables); - - if ( rc || (!scratch_page && !rmrr_found) ) - quarantine_teardown(pdev, drhd); - - return rc; + return 0; } =20 static const struct iommu_ops __initconst_cf_clobber vtd_ops =3D { diff --git a/xen/drivers/passthrough/x86/iommu.c b/xen/drivers/passthrough/= x86/iommu.c index 4a3fe059cb..a444e5813e 100644 --- a/xen/drivers/passthrough/x86/iommu.c +++ b/xen/drivers/passthrough/x86/iommu.c @@ -549,7 +549,6 @@ void __hwdom_init arch_iommu_hwdom_init(struct domain *= d) =20 void arch_pci_init_pdev(struct pci_dev *pdev) { - pdev->arch.pseudo_domid =3D DOMID_INVALID; } =20 unsigned long *__init iommu_init_domid(domid_t reserve) --=20 2.47.2 Teddy Astie | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech