]> Pileus Git - ~andy/linux/commitdiff
iommu/arm-smmu: add devices attached to the SMMU to an IOMMU group
authorAntonios Motakis <a.motakis@virtualopensystems.com>
Fri, 18 Oct 2013 15:08:29 +0000 (16:08 +0100)
committerWill Deacon <will.deacon@arm.com>
Mon, 16 Dec 2013 19:30:28 +0000 (19:30 +0000)
IOMMU groups are expected by certain users of the IOMMU API,
e.g. VFIO. Add new devices found by the SMMU driver to an IOMMU
group to satisfy those users.

Acked-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
drivers/iommu/arm-smmu.c

index e46a88700b6824c735967118281c9f7feb6e41b0..879da20617fb328d22e713975204d77a9efbfb09 100644 (file)
@@ -1494,6 +1494,13 @@ static int arm_smmu_add_device(struct device *dev)
 {
        struct arm_smmu_device *child, *parent, *smmu;
        struct arm_smmu_master *master = NULL;
+       struct iommu_group *group;
+       int ret;
+
+       if (dev->archdata.iommu) {
+               dev_warn(dev, "IOMMU driver already assigned to device\n");
+               return -EINVAL;
+       }
 
        spin_lock(&arm_smmu_devices_lock);
        list_for_each_entry(parent, &arm_smmu_devices, list) {
@@ -1526,13 +1533,23 @@ static int arm_smmu_add_device(struct device *dev)
        if (!master)
                return -ENODEV;
 
+       group = iommu_group_alloc();
+       if (IS_ERR(group)) {
+               dev_err(dev, "Failed to allocate IOMMU group\n");
+               return PTR_ERR(group);
+       }
+
+       ret = iommu_group_add_device(group, dev);
+       iommu_group_put(group);
        dev->archdata.iommu = smmu;
-       return 0;
+
+       return ret;
 }
 
 static void arm_smmu_remove_device(struct device *dev)
 {
        dev->archdata.iommu = NULL;
+       iommu_group_remove_device(dev);
 }
 
 static struct iommu_ops arm_smmu_ops = {