iommu: Move default domain allocation to separate function
authorJoerg Roedel <jroedel@suse.de>
Wed, 29 Apr 2020 13:36:39 +0000 (15:36 +0200)
committerJoerg Roedel <jroedel@suse.de>
Tue, 5 May 2020 12:36:12 +0000 (14:36 +0200)
Move the code out of iommu_group_get_for_dev() into a separate
function.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20200429133712.31431-2-joro@8bytes.org
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/iommu.c

index 2b47141..bfe0117 100644 (file)
@@ -1361,6 +1361,41 @@ struct iommu_group *fsl_mc_device_group(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(fsl_mc_device_group);
 
+static int iommu_alloc_default_domain(struct device *dev,
+                                     struct iommu_group *group)
+{
+       struct iommu_domain *dom;
+
+       if (group->default_domain)
+               return 0;
+
+       dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
+       if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
+               dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
+               if (dom) {
+                       dev_warn(dev,
+                                "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
+                                iommu_def_domain_type);
+               }
+       }
+
+       if (!dom)
+               return -ENOMEM;
+
+       group->default_domain = dom;
+       if (!group->domain)
+               group->domain = dom;
+
+       if (!iommu_dma_strict) {
+               int attr = 1;
+               iommu_domain_set_attr(dom,
+                                     DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
+                                     &attr);
+       }
+
+       return 0;
+}
+
 /**
  * iommu_group_get_for_dev - Find or create the IOMMU group for a device
  * @dev: target device
@@ -1393,40 +1428,21 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 
        /*
         * Try to allocate a default domain - needs support from the
-        * IOMMU driver.
+        * IOMMU driver. There are still some drivers which don't support
+        * default domains, so the return value is not yet checked.
         */
-       if (!group->default_domain) {
-               struct iommu_domain *dom;
-
-               dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
-               if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
-                       dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
-                       if (dom) {
-                               dev_warn(dev,
-                                        "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
-                                        iommu_def_domain_type);
-                       }
-               }
-
-               group->default_domain = dom;
-               if (!group->domain)
-                       group->domain = dom;
-
-               if (dom && !iommu_dma_strict) {
-                       int attr = 1;
-                       iommu_domain_set_attr(dom,
-                                             DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
-                                             &attr);
-               }
-       }
+       iommu_alloc_default_domain(dev, group);
 
        ret = iommu_group_add_device(group, dev);
-       if (ret) {
-               iommu_group_put(group);
-               return ERR_PTR(ret);
-       }
+       if (ret)
+               goto out_put_group;
 
        return group;
+
+out_put_group:
+       iommu_group_put(group);
+
+       return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(iommu_group_get_for_dev);