Skip to content

Commit

Permalink
intel-iommu: Implement iommu_device_group
Browse files Browse the repository at this point in the history
We generally have BDF granularity for devices, so we just need
to make sure devices aren't hidden behind PCIe-to-PCI bridges.
We can then make up a group number that's simply the concatenated
seg|bus|dev|fn so we don't have to track them (not that users
should depend on that).

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
  • Loading branch information
awilliam committed Nov 3, 2011
1 parent 37dd08c commit 63ca854
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions drivers/iommu/intel-iommu.c
Expand Up @@ -4060,6 +4060,49 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
return 0;
}

/* Group numbers are arbitrary. Device with the same group number
* indicate the iommu cannot differentiate between them. To avoid
* tracking used groups we just use the seg|bus|devfn of the lowest
* level we're able to differentiate devices */
static int intel_iommu_device_group(struct device *dev, unsigned int *groupid)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_dev *bridge;
union {
struct {
u8 devfn;
u8 bus;
u16 segment;
} pci;
u32 group;
} id;

if (iommu_no_mapping(dev))
return -ENODEV;

id.pci.segment = pci_domain_nr(pdev->bus);
id.pci.bus = pdev->bus->number;
id.pci.devfn = pdev->devfn;

if (!device_to_iommu(id.pci.segment, id.pci.bus, id.pci.devfn))
return -ENODEV;

bridge = pci_find_upstream_pcie_bridge(pdev);
if (bridge) {
if (pci_is_pcie(bridge)) {
id.pci.bus = bridge->subordinate->number;
id.pci.devfn = 0;
} else {
id.pci.bus = bridge->bus->number;
id.pci.devfn = bridge->devfn;
}
}

*groupid = id.group;

return 0;
}

static struct iommu_ops intel_iommu_ops = {
.domain_init = intel_iommu_domain_init,
.domain_destroy = intel_iommu_domain_destroy,
Expand All @@ -4069,6 +4112,7 @@ static struct iommu_ops intel_iommu_ops = {
.unmap = intel_iommu_unmap,
.iova_to_phys = intel_iommu_iova_to_phys,
.domain_has_cap = intel_iommu_domain_has_cap,
.device_group = intel_iommu_device_group,
};

static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
Expand Down

0 comments on commit 63ca854

Please sign in to comment.