aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2013-05-30 14:39:18 -0400
committerJoerg Roedel <joro@8bytes.org>2013-06-20 11:21:09 -0400
commitc14d26905d256565052dce99c35b02470162e679 (patch)
treed8e9c610c217a4cb0370cd572e60a0f09c8f181e /drivers/iommu
parent7cef33471a35c6973ddad2926e9e88c52e9e1c1b (diff)
iommu/{vt-d,amd}: Remove multifunction assumption around grouping
If a device is multifunction and does not have ACS enabled then we assume that the entire package lacks ACS and use function 0 as the base of the group. The PCIe spec however states that components are permitted to implement ACS on some, none, or all of their applicable functions. It's therefore conceivable that function 0 may be fully independent and support ACS while other functions do not. Instead use the lowest function of the slot that does not have ACS enabled as the base of the group. This may be the current device, which is intentional. So long as we use a consistent algorithm, all the non-ACS functions will be grouped together and ACS functions will get separate groups. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Joerg Roedel <joro@8bytes.org>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/amd_iommu.c25
-rw-r--r--drivers/iommu/intel-iommu.c25
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,