aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/intel-iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r--drivers/iommu/intel-iommu.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 7469b534664..2297ec193eb 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2008,6 +2008,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
2008 if (!drhd) { 2008 if (!drhd) {
2009 printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", 2009 printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
2010 pci_name(pdev)); 2010 pci_name(pdev));
2011 free_domain_mem(domain);
2011 return NULL; 2012 return NULL;
2012 } 2013 }
2013 iommu = drhd->iommu; 2014 iommu = drhd->iommu;
@@ -4124,8 +4125,13 @@ static int intel_iommu_add_device(struct device *dev)
4124 } else 4125 } else
4125 dma_pdev = pci_dev_get(pdev); 4126 dma_pdev = pci_dev_get(pdev);
4126 4127
4128 /* Account for quirked devices */
4127 swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); 4129 swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
4128 4130
4131 /*
4132 * If it's a multifunction device that does not support our
4133 * required ACS flags, add to the same group as function 0.
4134 */
4129 if (dma_pdev->multifunction && 4135 if (dma_pdev->multifunction &&
4130 !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) 4136 !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
4131 swap_pci_ref(&dma_pdev, 4137 swap_pci_ref(&dma_pdev,
@@ -4133,14 +4139,28 @@ static int intel_iommu_add_device(struct device *dev)
4133 PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), 4139 PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
4134 0))); 4140 0)));
4135 4141
4142 /*
4143 * Devices on the root bus go through the iommu. If that's not us,
4144 * find the next upstream device and test ACS up to the root bus.
4145 * Finding the next device may require skipping virtual buses.
4146 */
4136 while (!pci_is_root_bus(dma_pdev->bus)) { 4147 while (!pci_is_root_bus(dma_pdev->bus)) {
4137 if (pci_acs_path_enabled(dma_pdev->bus->self, 4148 struct pci_bus *bus = dma_pdev->bus;
4138 NULL, REQ_ACS_FLAGS)) 4149
4150 while (!bus->self) {
4151 if (!pci_is_root_bus(bus))
4152 bus = bus->parent;
4153 else
4154 goto root_bus;
4155 }
4156
4157 if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
4139 break; 4158 break;
4140 4159
4141 swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); 4160 swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
4142 } 4161 }
4143 4162
4163root_bus:
4144 group = iommu_group_get(&dma_pdev->dev); 4164 group = iommu_group_get(&dma_pdev->dev);
4145 pci_dev_put(dma_pdev); 4165 pci_dev_put(dma_pdev);
4146 if (!group) { 4166 if (!group) {