diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-07-30 09:25:07 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-07-30 09:25:07 +0100 |
commit | cada0c18f8d184ca8ae902d720b9b95ee7b971ad (patch) | |
tree | 4070a434086e74b90787afd1f08dbcf4fb730d51 | |
parent | 1a1af72f08d4d0603f6086c8df8326276a779a6f (diff) | |
download | xen-cada0c18f8d184ca8ae902d720b9b95ee7b971ad.tar.gz xen-cada0c18f8d184ca8ae902d720b9b95ee7b971ad.tar.bz2 xen-cada0c18f8d184ca8ae902d720b9b95ee7b971ad.zip |
vtd: Move dom0 RMRR check to intel_iommu_remove_device()
If put dom0 RMRR check in domain_context_unmap_one(), the devices with
RMRR cannot be assigned to other domain, becuase
domain_context_unmap_one() won't unmap context for them, and dom0
always owns them. This patch moves the check to intel_iommu_remove_device()
which is only called by dom0 hypercall. This not only guarantees
keeping RMRR mappings for dom0 during its booting, but also won't
impact device assignment.
Signed-off-by: Weidong Han <weidong.han@intel.com>
-rw-r--r-- | xen/drivers/passthrough/vtd/iommu.c | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 0fd17e0f6c..b5454f4108 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1302,10 +1302,6 @@ static int domain_context_unmap_one( struct context_entry *context, *context_entries; unsigned long flags; u64 maddr; - struct acpi_rmrr_unit *rmrr; - u16 bdf; - int i; - unsigned int is_rmrr_device = 0; maddr = bus_to_context_maddr(iommu, bus); context_entries = (struct context_entry *)map_vtd_domain_page(maddr); @@ -1318,25 +1314,11 @@ static int domain_context_unmap_one( } spin_lock_irqsave(&iommu->lock, flags); - if ( domain->domain_id == 0 ) - { - for_each_rmrr_device ( rmrr, bdf, i ) - { - if ( PCI_BUS(bdf) == bus && PCI_DEVFN2(bdf) == devfn ) - { - is_rmrr_device = 1; - break; - } - } - } - if ( !is_rmrr_device ) - { - context_clear_present(*context); - context_clear_entry(*context); - iommu_flush_cache_entry(context); - iommu_flush_context_domain(iommu, domain_iommu_domid(domain), 0); - iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0); - } + context_clear_present(*context); + context_clear_entry(*context); + iommu_flush_cache_entry(context); + iommu_flush_context_domain(iommu, domain_iommu_domid(domain), 0); + iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0); unmap_vtd_domain_page(context_entries); spin_unlock_irqrestore(&iommu->lock, flags); @@ -1619,8 +1601,26 @@ static int intel_iommu_add_device(struct pci_dev *pdev) static int intel_iommu_remove_device(struct pci_dev *pdev) { + struct acpi_rmrr_unit *rmrr; + u16 bdf; + int i; + if ( !pdev->domain ) return -EINVAL; + + /* If the device belongs to dom0, and it has RMRR, don't remove it + * from dom0, because BIOS may use RMRR at booting time. + */ + if ( pdev->domain->domain_id == 0 ) + { + for_each_rmrr_device ( rmrr, bdf, i ) + { + if ( PCI_BUS(bdf) == pdev->bus && + PCI_DEVFN2(bdf) == pdev->devfn ) + return 0; + } + } + return domain_context_unmap(pdev->domain, pdev->bus, pdev->devfn); } |