From: Joerg Roedel <jroedel@suse.de>
Date: Wed, 29 Apr 2020 15:36:39 +0200
Subject: iommu: Move default domain allocation to separate function
Git-commit: ff2a08b39bcede1b08d84d8b5c8ee1336a39c5df
Patch-mainline: v5.8-rc1
References: bsc#1175713
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 | 74 +++++++++++++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 29 deletions(-)
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1371,6 +1371,41 @@ struct iommu_group *fsl_mc_device_group(
}
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
@@ -1403,40 +1438,21 @@ struct iommu_group *iommu_group_get_for_
/*
* 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_GPL(iommu_group_get_for_dev);