Add IOMMU group support to Intel VT-d code.  This driver sets up
devices ondemand, so make use of the add_device/remove_device
callbacks in IOMMU API to manage setting up the groups.

Signed-off-by: Alex Williamson <alex.william...@redhat.com>
---

 drivers/iommu/intel-iommu.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index c62f2df..4a43452 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4090,6 +4090,47 @@ static int intel_iommu_domain_has_cap(struct 
iommu_domain *domain,
        return 0;
 }
 
+static int intel_iommu_add_device(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct pci_dev *bridge, *dma_pdev;
+       struct iommu_group *group;
+       int ret;
+
+       if (!device_to_iommu(pci_domain_nr(pdev->bus),
+                            pdev->bus->number, pdev->devfn))
+               return -ENODEV;
+
+       bridge = pci_find_upstream_pcie_bridge(pdev);
+       if (bridge) {
+               if (pci_is_pcie(bridge))
+                       dma_pdev = pci_get_domain_bus_and_slot(
+                                               pci_domain_nr(pdev->bus),
+                                               bridge->subordinate->number, 0);
+               else
+                       dma_pdev = pci_dev_get(bridge);
+       } else
+               dma_pdev = pci_dev_get(pdev);
+
+       group = iommu_group_get(&dma_pdev->dev);
+       pci_dev_put(dma_pdev);
+       if (!group) {
+               group = iommu_group_alloc();
+               if (IS_ERR(group))
+                       return PTR_ERR(group);
+       }
+
+       ret = iommu_group_add_device(group, dev);
+
+       iommu_group_put(group);
+       return ret;
+}
+
+static void intel_iommu_remove_device(struct device *dev)
+{
+       iommu_group_remove_device(dev);
+}
+
 static struct iommu_ops intel_iommu_ops = {
        .domain_init    = intel_iommu_domain_init,
        .domain_destroy = intel_iommu_domain_destroy,
@@ -4099,6 +4140,8 @@ 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,
+       .add_device     = intel_iommu_add_device,
+       .remove_device  = intel_iommu_remove_device,
        .pgsize_bitmap  = INTEL_IOMMU_PGSIZES,
 };
 

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to