Merge branches 'x86/vt-d', 'arm/omap', 'core', 'x86/amd' and 'arm/smmu' into next
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / iommu / amd_iommu.c
index 4b029c1..6dc6594 100644 (file)
@@ -287,14 +287,27 @@ static struct pci_dev *get_isolation_root(struct pci_dev *pdev)
 
        /*
         * If it's a multifunction device that does not support our
-        * required ACS flags, add to the same group as function 0.
+        * required ACS flags, add to the same group as lowest numbered
+        * function that also does not suport the required ACS flags.
         */
        if (dma_pdev->multifunction &&
-           !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
-               swap_pci_ref(&dma_pdev,
-                            pci_get_slot(dma_pdev->bus,
-                                         PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
-                                         0)));
+           !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
+               u8 i, slot = PCI_SLOT(dma_pdev->devfn);
+
+               for (i = 0; i < 8; i++) {
+                       struct pci_dev *tmp;
+
+                       tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
+                       if (!tmp)
+                               continue;
+
+                       if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
+                               swap_pci_ref(&dma_pdev, tmp);
+                               break;
+                       }
+                       pci_dev_put(tmp);
+               }
+       }
 
        /*
         * Devices on the root bus go through the iommu.  If that's not us,