aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-07-25 09:44:48 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-07-25 09:44:48 +0100
commitfa88cfadf9181165aaa5440d0429fee7a520e4df (patch)
treecbdc86e8d7cad33b0f40cdf771cb531dc0558e53
parentdba5b800e38f85fc8b5f30d35224cabf4cc12fb5 (diff)
downloadxen-fa88cfadf9181165aaa5440d0429fee7a520e4df.tar.gz
xen-fa88cfadf9181165aaa5440d0429fee7a520e4df.tar.bz2
xen-fa88cfadf9181165aaa5440d0429fee7a520e4df.zip
vt-d: Map RMRR in intel_iommu_add_device() if the device has RMRR;
move domain_context_mapping() to be in front of list_move() in reassign_device_ownership(). Signed-off-by: Weidong Han <weidong.han@intel.com>
-rw-r--r--xen/drivers/passthrough/vtd/iommu.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 1090cee821..0fd17e0f6c 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1409,12 +1409,15 @@ static int reassign_device_ownership(
pdev_iommu = drhd->iommu;
domain_context_unmap(source, bus, devfn);
+ ret = domain_context_mapping(target, bus, devfn);
+ if ( ret )
+ return ret;
+
write_lock(&pcidevs_lock);
list_move(&pdev->domain_list, &target->arch.pdev_list);
write_unlock(&pcidevs_lock);
pdev->domain = target;
- ret = domain_context_mapping(target, bus, devfn);
spin_unlock(&pdev->lock);
read_lock(&pcidevs_lock);
@@ -1583,9 +1586,35 @@ static int iommu_prepare_rmrr_dev(struct domain *d,
static int intel_iommu_add_device(struct pci_dev *pdev)
{
+ struct acpi_rmrr_unit *rmrr;
+ u16 bdf;
+ int ret, i;
+
if ( !pdev->domain )
return -EINVAL;
- return domain_context_mapping(pdev->domain, pdev->bus, pdev->devfn);
+
+ ret = domain_context_mapping(pdev->domain, pdev->bus, pdev->devfn);
+ if ( ret )
+ {
+ gdprintk(XENLOG_ERR VTDPREFIX,
+ "intel_iommu_add_device: context mapping failed\n");
+ return ret;
+ }
+
+ for_each_rmrr_device ( rmrr, bdf, i )
+ {
+ if ( PCI_BUS(bdf) == pdev->bus && PCI_DEVFN2(bdf) == pdev->devfn )
+ {
+ ret = iommu_prepare_rmrr_dev(pdev->domain, rmrr,
+ pdev->bus, pdev->devfn);
+ if ( ret )
+ gdprintk(XENLOG_ERR VTDPREFIX,
+ "intel_iommu_add_device: RMRR mapping failed\n");
+ break;
+ }
+ }
+
+ return ret;
}
static int intel_iommu_remove_device(struct pci_dev *pdev)