This callback requests the driver to create only a __IOMMU_DOMAIN_PAGING domain, so it saves a few lines in a lot of drivers needlessly checking the type. More critically, this allows us to sweep out all the IOMMU_DOMAIN_UNMANAGED and IOMMU_DOMAIN_DMA checks from a lot of the drivers, simplifying what is going on in the code and ultimately removing the now-unused special cases in drivers where they did not support IOMMU_DOMAIN_DMA. domain_alloc_paging() should return a struct iommu_domain that is functionally compatible with ARM_DMA_USE_IOMMU, dma-iommu.c and iommufd. Be forwards looking and pass in a 'struct device *' argument. We can provide this when allocating the default_domain. No drivers will look at this. Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> --- drivers/iommu/iommu.c | 40 ++++++++++++++++++++++++---------------- include/linux/iommu.h | 2 ++ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index f20a031e2910b2..fee417df8f195d 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -93,6 +93,7 @@ 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(struct bus_type *bus, + struct device *dev, unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev); @@ -1618,12 +1619,12 @@ static int iommu_get_def_domain_type(struct device *dev) } static struct iommu_domain * -__iommu_group_alloc_default_domain(struct bus_type *bus, +__iommu_group_alloc_default_domain(struct group_device *gdev, 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_domain_alloc(gdev->dev->bus, gdev->dev, req_type); } /* @@ -1633,9 +1634,9 @@ __iommu_group_alloc_default_domain(struct bus_type *bus, static struct iommu_domain * iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) { - struct bus_type *bus = - list_first_entry(&group->devices, struct group_device, list) - ->dev->bus; + struct group_device *gdev = + list_first_entry(&group->devices, struct group_device, list); + const struct iommu_ops *ops = dev_iommu_ops(gdev->dev); struct iommu_domain *dom; lockdep_assert_held(&group->mutex); @@ -1645,14 +1646,15 @@ 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(gdev, group, + req_type); /* * If ARM32 CONFIG_ARM_DMA_USE_IOMMU is enabled and the driver doesn't @@ -1665,18 +1667,19 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) IS_ENABLED(CONFIG_IOMMU_DMA))); return __iommu_group_alloc_default_domain( - bus, group, IOMMU_DOMAIN_IDENTITY); + gdev, group, IOMMU_DOMAIN_IDENTITY); } /* 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(gdev, 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(gdev, group, IOMMU_DOMAIN_DMA); if (!dom) return NULL; @@ -1930,6 +1933,7 @@ void iommu_set_fault_handler(struct iommu_domain *domain, EXPORT_SYMBOL_GPL(iommu_set_fault_handler); static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, + struct device *dev, unsigned type) { struct iommu_domain *domain; @@ -1940,7 +1944,11 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, if (type == IOMMU_DOMAIN_IDENTITY && bus->iommu_ops->identity_domain) return bus->iommu_ops->identity_domain; - domain = bus->iommu_ops->domain_alloc(type); + if ((type == IOMMU_DOMAIN_UNMANAGED || type == IOMMU_DOMAIN_DMA) && + bus->iommu_ops->domain_alloc_paging) + domain = bus->iommu_ops->domain_alloc_paging(dev); + else + domain = bus->iommu_ops->domain_alloc(type); if (!domain) return NULL; @@ -1964,7 +1972,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, struct iommu_domain *iommu_domain_alloc(struct bus_type *bus) { - return __iommu_domain_alloc(bus, IOMMU_DOMAIN_UNMANAGED); + return __iommu_domain_alloc(bus, NULL, IOMMU_DOMAIN_UNMANAGED); } EXPORT_SYMBOL_GPL(iommu_domain_alloc); @@ -3079,15 +3087,15 @@ static int __iommu_group_alloc_blocking_domain(struct iommu_group *group) if (group->blocking_domain) return 0; - group->blocking_domain = - __iommu_domain_alloc(dev->dev->bus, IOMMU_DOMAIN_BLOCKED); + group->blocking_domain = __iommu_domain_alloc(dev->dev->bus, dev->dev, + 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); + dev->dev->bus, dev->dev, IOMMU_DOMAIN_UNMANAGED); if (!group->blocking_domain) return -EINVAL; } diff --git a/include/linux/iommu.h b/include/linux/iommu.h index f6a28ab78e607e..cc9aff2d213eec 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -227,6 +227,7 @@ struct iommu_iotlb_gather { * struct iommu_ops - iommu ops and capabilities * @capable: check capability * @domain_alloc: allocate iommu domain + * @domain_alloc_paging: Allocate an IOMMU_DOMAIN_UNMANAGED * @probe_device: Add device to iommu driver handling * @release_device: Remove device from iommu driver handling * @probe_finalize: Do final setup work after the device is added to an IOMMU @@ -258,6 +259,7 @@ struct iommu_ops { /* Domain allocation and freeing by the iommu driver */ struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type); + struct iommu_domain *(*domain_alloc_paging)(struct device *dev); struct iommu_device *(*probe_device)(struct device *dev); void (*release_device)(struct device *dev); -- 2.40.0