Allocate a domain from a group. Automatically obtains the iommu_ops to use
from the device list of the group. Convert the internal callers to use it.

Signed-off-by: Jason Gunthorpe <j...@nvidia.com>
---
 drivers/iommu/iommu.c | 66 ++++++++++++++++++++++++-------------------
 1 file changed, 37 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 15cdfca4011ef2..c4cac1dcf80610 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -94,8 +94,8 @@ static const char * const iommu_group_resv_type_string[] = {
 static int iommu_bus_notifier(struct notifier_block *nb,
                              unsigned long action, void *data);
 static void iommu_release_device(struct device *dev);
-static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus,
-                                                unsigned type);
+static struct iommu_domain *
+__iommu_group_domain_alloc(struct iommu_group *group, unsigned int type);
 static int __iommu_attach_device(struct iommu_domain *domain,
                                 struct device *dev);
 static int __iommu_attach_group(struct iommu_domain *domain,
@@ -1652,12 +1652,11 @@ struct iommu_group *fsl_mc_device_group(struct device 
*dev)
 EXPORT_SYMBOL_GPL(fsl_mc_device_group);
 
 static struct iommu_domain *
-__iommu_group_alloc_default_domain(const struct bus_type *bus,
-                                  struct iommu_group *group, int req_type)
+__iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
 {
        if (group->default_domain && group->default_domain->type == req_type)
                return group->default_domain;
-       return __iommu_domain_alloc(bus, req_type);
+       return __iommu_group_domain_alloc(group, req_type);
 }
 
 /*
@@ -1667,9 +1666,10 @@ __iommu_group_alloc_default_domain(const struct bus_type 
*bus,
 static struct iommu_domain *
 iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
 {
-       const struct bus_type *bus =
+       struct device *dev =
                list_first_entry(&group->devices, struct group_device, list)
-                       ->dev->bus;
+                       ->dev;
+       const struct iommu_ops *ops = dev_iommu_ops(dev);
        struct iommu_domain *dom;
 
        lockdep_assert_held(&group->mutex);
@@ -1679,24 +1679,24 @@ iommu_group_alloc_default_domain(struct iommu_group 
*group, int req_type)
         * domain. This should always be either an IDENTITY or PLATFORM domain.
         * Do not use in new drivers.
         */
-       if (bus->iommu_ops->default_domain) {
+       if (ops->default_domain) {
                if (req_type)
                        return ERR_PTR(-EINVAL);
-               return bus->iommu_ops->default_domain;
+               return ops->default_domain;
        }
 
        if (req_type)
-               return __iommu_group_alloc_default_domain(bus, group, req_type);
+               return __iommu_group_alloc_default_domain(group, req_type);
 
        /* The driver gave no guidance on what type to use, try the default */
-       dom = __iommu_group_alloc_default_domain(bus, group, 
iommu_def_domain_type);
+       dom = __iommu_group_alloc_default_domain(group, iommu_def_domain_type);
        if (dom)
                return dom;
 
        /* Otherwise IDENTITY and DMA_FQ defaults will try DMA */
        if (iommu_def_domain_type == IOMMU_DOMAIN_DMA)
                return NULL;
-       dom = __iommu_group_alloc_default_domain(bus, group, IOMMU_DOMAIN_DMA);
+       dom = __iommu_group_alloc_default_domain(group, IOMMU_DOMAIN_DMA);
        if (!dom)
                return NULL;
 
@@ -1994,18 +1994,15 @@ void iommu_set_fault_handler(struct iommu_domain 
*domain,
 }
 EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
 
-static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus,
-                                                unsigned type)
+static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops,
+                                                unsigned int type)
 {
        struct iommu_domain *domain;
 
-       if (bus == NULL || bus->iommu_ops == NULL)
-               return NULL;
+       if (type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain)
+               return ops->identity_domain;
 
-       if (type == IOMMU_DOMAIN_IDENTITY && bus->iommu_ops->identity_domain)
-               return bus->iommu_ops->identity_domain;
-
-       domain = bus->iommu_ops->domain_alloc(type);
+       domain = ops->domain_alloc(type);
        if (!domain)
                return NULL;
 
@@ -2015,10 +2012,10 @@ static struct iommu_domain *__iommu_domain_alloc(const 
struct bus_type *bus,
         * may override this later
         */
        if (!domain->pgsize_bitmap)
-               domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap;
+               domain->pgsize_bitmap = ops->pgsize_bitmap;
 
        if (!domain->ops)
-               domain->ops = bus->iommu_ops->default_domain_ops;
+               domain->ops = ops->default_domain_ops;
 
        if (iommu_is_dma_domain(domain) && iommu_get_dma_cookie(domain)) {
                iommu_domain_free(domain);
@@ -2027,9 +2024,23 @@ static struct iommu_domain *__iommu_domain_alloc(const 
struct bus_type *bus,
        return domain;
 }
 
+static struct iommu_domain *
+__iommu_group_domain_alloc(struct iommu_group *group, unsigned int type)
+{
+       struct device *dev =
+               list_first_entry(&group->devices, struct group_device, list)
+                       ->dev;
+
+       lockdep_assert_held(&group->mutex);
+
+       return __iommu_domain_alloc(dev_iommu_ops(dev), type);
+}
+
 struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus)
 {
-       return __iommu_domain_alloc(bus, IOMMU_DOMAIN_UNMANAGED);
+       if (bus == NULL || bus->iommu_ops == NULL)
+               return NULL;
+       return __iommu_domain_alloc(bus->iommu_ops, IOMMU_DOMAIN_UNMANAGED);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_alloc);
 
@@ -3138,21 +3149,18 @@ void iommu_device_unuse_default_domain(struct device 
*dev)
 
 static int __iommu_group_alloc_blocking_domain(struct iommu_group *group)
 {
-       struct group_device *dev =
-               list_first_entry(&group->devices, struct group_device, list);
-
        if (group->blocking_domain)
                return 0;
 
        group->blocking_domain =
-               __iommu_domain_alloc(dev->dev->bus, IOMMU_DOMAIN_BLOCKED);
+               __iommu_group_domain_alloc(group, IOMMU_DOMAIN_BLOCKED);
        if (!group->blocking_domain) {
                /*
                 * For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED
                 * create an empty domain instead.
                 */
-               group->blocking_domain = __iommu_domain_alloc(
-                       dev->dev->bus, IOMMU_DOMAIN_UNMANAGED);
+               group->blocking_domain = __iommu_group_domain_alloc(
+                       group, IOMMU_DOMAIN_UNMANAGED);
                if (!group->blocking_domain)
                        return -EINVAL;
        }
-- 
2.40.1

Reply via email to