Skip to content

Commit

Permalink
amd_iommu: Make use of DMA quirks and ACS checks in IOMMU groups
Browse files Browse the repository at this point in the history
Work around broken devices and adhere to ACS support when determining
IOMMU grouping.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
  • Loading branch information
Alex Williamson authored and Joerg Roedel committed Jun 25, 2012
1 parent abdfdde commit 664b600
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions drivers/iommu/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,14 @@ static bool check_device(struct device *dev)
return true;
}

static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
{
pci_dev_put(*from);
*from = to;
}

#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)

static int iommu_init_device(struct device *dev)
{
struct pci_dev *dma_pdev, *pdev = to_pci_dev(dev);
Expand Down Expand Up @@ -286,6 +294,23 @@ static int iommu_init_device(struct device *dev)
} else
dma_pdev = pci_dev_get(pdev);

swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));

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)));

while (!pci_is_root_bus(dma_pdev->bus)) {
if (pci_acs_path_enabled(dma_pdev->bus->self,
NULL, REQ_ACS_FLAGS))
break;

swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self));
}

group = iommu_group_get(&dma_pdev->dev);
pci_dev_put(dma_pdev);
if (!group) {
Expand Down

0 comments on commit 664b600

Please sign in to comment.