diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-21 12:49:04 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-24 10:08:10 -0400 |
commit | cf04eee8bf0e842dd73a64d02cdcdcbb31b0102c (patch) | |
tree | 25999470a60240579207c526efe4c449007202f0 /drivers/iommu/intel-iommu.c | |
parent | 66077edc972c1c8dc2cf08e96a956c2db9bd705c (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.c | 61 |
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 | ||
2598 | static 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 | |||
2598 | static int __init iommu_prepare_static_identity_mapping(int hw) | 2619 | static 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 | } |