aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-07-30 09:25:07 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-07-30 09:25:07 +0100
commitcada0c18f8d184ca8ae902d720b9b95ee7b971ad (patch)
tree4070a434086e74b90787afd1f08dbcf4fb730d51
parent1a1af72f08d4d0603f6086c8df8326276a779a6f (diff)
downloadxen-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.c46
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);
}