diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-07-25 09:44:48 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-07-25 09:44:48 +0100 |
commit | fa88cfadf9181165aaa5440d0429fee7a520e4df (patch) | |
tree | cbdc86e8d7cad33b0f40cdf771cb531dc0558e53 | |
parent | dba5b800e38f85fc8b5f30d35224cabf4cc12fb5 (diff) | |
download | xen-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.c | 33 |
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) |