aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/intel-iommu.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2014-03-21 12:49:04 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2014-03-24 10:08:10 -0400
commitcf04eee8bf0e842dd73a64d02cdcdcbb31b0102c (patch)
tree25999470a60240579207c526efe4c449007202f0 /drivers/iommu/intel-iommu.c
parent66077edc972c1c8dc2cf08e96a956c2db9bd705c (diff)
iommu/vt-d: Include ACPI devices in iommu=pt
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r--drivers/iommu/intel-iommu.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a180f10a7b26..6fbce01b7875 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2595,30 +2595,65 @@ static int iommu_should_identity_map(struct device *dev, int startup)
2595 return 1; 2595 return 1;
2596} 2596}
2597 2597
2598static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2599{
2600 int ret;
2601
2602 if (!iommu_should_identity_map(dev, 1))
2603 return 0;
2604
2605 ret = domain_add_dev_info(si_domain, dev,
2606 hw ? CONTEXT_TT_PASS_THROUGH :
2607 CONTEXT_TT_MULTI_LEVEL);
2608 if (!ret)
2609 pr_info("IOMMU: %s identity mapping for device %s\n",
2610 hw ? "hardware" : "software", dev_name(dev));
2611 else if (ret == -ENODEV)
2612 /* device not associated with an iommu */
2613 ret = 0;
2614
2615 return ret;
2616}
2617
2618
2598static int __init iommu_prepare_static_identity_mapping(int hw) 2619static int __init iommu_prepare_static_identity_mapping(int hw)
2599{ 2620{
2600 struct pci_dev *pdev = NULL; 2621 struct pci_dev *pdev = NULL;
2601 int ret; 2622 struct dmar_drhd_unit *drhd;
2623 struct intel_iommu *iommu;
2624 struct device *dev;
2625 int i;
2626 int ret = 0;
2602 2627
2603 ret = si_domain_init(hw); 2628 ret = si_domain_init(hw);
2604 if (ret) 2629 if (ret)
2605 return -EFAULT; 2630 return -EFAULT;
2606 2631
2607 for_each_pci_dev(pdev) { 2632 for_each_pci_dev(pdev) {
2608 if (iommu_should_identity_map(&pdev->dev, 1)) { 2633 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2609 ret = domain_add_dev_info(si_domain, &pdev->dev, 2634 if (ret)
2610 hw ? CONTEXT_TT_PASS_THROUGH : 2635 return ret;
2611 CONTEXT_TT_MULTI_LEVEL); 2636 }
2612 if (ret) { 2637
2613 /* device not associated with an iommu */ 2638 for_each_active_iommu(iommu, drhd)
2614 if (ret == -ENODEV) 2639 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2615 continue; 2640 struct acpi_device_physical_node *pn;
2616 return ret; 2641 struct acpi_device *adev;
2642
2643 if (dev->bus != &acpi_bus_type)
2644 continue;
2645
2646 adev= to_acpi_device(dev);
2647 mutex_lock(&adev->physical_node_lock);
2648 list_for_each_entry(pn, &adev->physical_node_list, node) {
2649 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2650 if (ret)
2651 break;
2617 } 2652 }
2618 pr_info("IOMMU: %s identity mapping for device %s\n", 2653 mutex_unlock(&adev->physical_node_lock);
2619 hw ? "hardware" : "software", pci_name(pdev)); 2654 if (ret)
2655 return ret;
2620 } 2656 }
2621 }
2622 2657
2623 return 0; 2658 return 0;
2624} 2659}