diff options
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 25 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 25 |
2 files changed, 38 insertions, 12 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 21d02b0d907c..5a02d0776a66 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -287,14 +287,27 @@ static struct pci_dev *get_isolation_root(struct pci_dev *pdev) | |||
287 | 287 | ||
288 | /* | 288 | /* |
289 | * If it's a multifunction device that does not support our | 289 | * If it's a multifunction device that does not support our |
290 | * required ACS flags, add to the same group as function 0. | 290 | * required ACS flags, add to the same group as lowest numbered |
291 | * function that also does not suport the required ACS flags. | ||
291 | */ | 292 | */ |
292 | if (dma_pdev->multifunction && | 293 | if (dma_pdev->multifunction && |
293 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 294 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) { |
294 | swap_pci_ref(&dma_pdev, | 295 | u8 i, slot = PCI_SLOT(dma_pdev->devfn); |
295 | pci_get_slot(dma_pdev->bus, | 296 | |
296 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 297 | for (i = 0; i < 8; i++) { |
297 | 0))); | 298 | struct pci_dev *tmp; |
299 | |||
300 | tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i)); | ||
301 | if (!tmp) | ||
302 | continue; | ||
303 | |||
304 | if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) { | ||
305 | swap_pci_ref(&dma_pdev, tmp); | ||
306 | break; | ||
307 | } | ||
308 | pci_dev_put(tmp); | ||
309 | } | ||
310 | } | ||
298 | 311 | ||
299 | /* | 312 | /* |
300 | * Devices on the root bus go through the iommu. If that's not us, | 313 | * Devices on the root bus go through the iommu. If that's not us, |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index b4f0e28dfa41..eec0d3e04bf5 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -4182,14 +4182,27 @@ static int intel_iommu_add_device(struct device *dev) | |||
4182 | 4182 | ||
4183 | /* | 4183 | /* |
4184 | * If it's a multifunction device that does not support our | 4184 | * If it's a multifunction device that does not support our |
4185 | * required ACS flags, add to the same group as function 0. | 4185 | * required ACS flags, add to the same group as lowest numbered |
4186 | * function that also does not suport the required ACS flags. | ||
4186 | */ | 4187 | */ |
4187 | if (dma_pdev->multifunction && | 4188 | if (dma_pdev->multifunction && |
4188 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 4189 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) { |
4189 | swap_pci_ref(&dma_pdev, | 4190 | u8 i, slot = PCI_SLOT(dma_pdev->devfn); |
4190 | pci_get_slot(dma_pdev->bus, | 4191 | |
4191 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 4192 | for (i = 0; i < 8; i++) { |
4192 | 0))); | 4193 | struct pci_dev *tmp; |
4194 | |||
4195 | tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i)); | ||
4196 | if (!tmp) | ||
4197 | continue; | ||
4198 | |||
4199 | if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) { | ||
4200 | swap_pci_ref(&dma_pdev, tmp); | ||
4201 | break; | ||
4202 | } | ||
4203 | pci_dev_put(tmp); | ||
4204 | } | ||
4205 | } | ||
4193 | 4206 | ||
4194 | /* | 4207 | /* |
4195 | * Devices on the root bus go through the iommu. If that's not us, | 4208 | * Devices on the root bus go through the iommu. If that's not us, |