When a device is setup for passthrough it has full access to memory so processing the RMRRs is unnecessary. However, if we remove the device from the si_domain, we need to reinstate the associated RMRRs. Signed-off-by: Alex Williamson <alex.williamson@xxxxxx> --- drivers/pci/intel-iommu.c | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+), 0 deletions(-) diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 19f10ae..a7f4476 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2538,6 +2538,10 @@ static int iommu_no_mapping(struct device *dev) if (iommu_should_identity_map(pdev, 0)) return 1; else { + struct dmar_rmrr_unit *rmrr; + struct dmar_domain *domain; + int i, ret; + /* * Devices that cannot support identity mapping * are removed from si_domain and fall back to @@ -2546,6 +2550,35 @@ static int iommu_no_mapping(struct device *dev) domain_remove_one_dev_info(si_domain, pdev); printk(KERN_INFO "%s uses non-identity mapping\n", pci_name(pdev)); + + domain = get_valid_domain_for_dev(pdev); + if (!domain) { + printk(KERN_ERR + "Allocating domain for %s failed", + pci_name(pdev)); + return 0; + } + + ret = domain_add_dev_info(domain, pdev, + CONTEXT_TT_MULTI_LEVEL); + if (ret) { + printk(KERN_ERR + "Attaching %s to domain failed", + pci_name(pdev)); + return 0; + } + + for_each_rmrr_units(rmrr) { + for (i = 0; i < rmrr->devices_cnt; i++) { + if (pdev != rmrr->devices[i]) + continue; + ret = iommu_prepare_rmrr_dev(rmrr, + pdev); + if (ret) + printk(KERN_ERR + "IOMMU: mapping reserved region failed\n"); + } + } return 0; } } else { -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html