diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 4da09bbcc8..1b1b11cb04 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1636,7 +1636,7 @@ int domain_context_mapping_one( if ( !seg && !rc ) rc = me_wifi_quirk(domain, bus, devfn, domid, pgd_maddr, mode); - if ( rc ) + if ( rc && !(mode & MAP_ERROR_RECOVERY) ) { if ( !prev_dom || /* @@ -1646,11 +1646,12 @@ int domain_context_mapping_one( */ (prev_dom == dom_io && !pdev) ) domain_context_unmap_one(domain, iommu, bus, devfn); - else if ( prev_dom != domain ) /* Avoid infinite recursion. */ + else domain_context_mapping_one(prev_dom, iommu, bus, devfn, pdev, DEVICE_DOMID(prev_dom, pdev), DEVICE_PGTABLE(prev_dom, pdev), - mode & MAP_WITH_RMRR); + (mode & MAP_WITH_RMRR) + | MAP_ERROR_RECOVERY); } if ( prev_dom ) diff --git a/xen/drivers/passthrough/vtd/vtd.h b/xen/drivers/passthrough/vtd/vtd.h index e4ab242fee..cb2df76eed 100644 --- a/xen/drivers/passthrough/vtd/vtd.h +++ b/xen/drivers/passthrough/vtd/vtd.h @@ -29,7 +29,8 @@ #define MAP_WITH_RMRR (1u << 0) #define MAP_OWNER_DYING (1u << 1) #define MAP_SINGLE_DEVICE (1u << 2) -#define UNMAP_ME_PHANTOM_FUNC (1u << 3) +#define MAP_ERROR_RECOVERY (1u << 3) +#define UNMAP_ME_PHANTOM_FUNC (1u << 4) /* Allow for both IOAPIC and IOSAPIC. */ #define IO_xAPIC_route_entry IO_APIC_route_entry