iommu: Add __iommu_group_domain_alloc()
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. Tested-by: Steven Price <steven.price@arm.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/21-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
98ac73f99b
commit
8359cf39ac
@ -96,8 +96,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,
|
||||
@ -1719,12 +1719,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1751,9 +1750,7 @@ static const struct iommu_ops *group_iommu_ops(struct iommu_group *group)
|
||||
static struct iommu_domain *
|
||||
iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
|
||||
{
|
||||
const struct bus_type *bus =
|
||||
list_first_entry(&group->devices, struct group_device, list)
|
||||
->dev->bus;
|
||||
const struct iommu_ops *ops = group_iommu_ops(group);
|
||||
struct iommu_domain *dom;
|
||||
|
||||
lockdep_assert_held(&group->mutex);
|
||||
@ -1763,24 +1760,24 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
|
||||
* domain. This should always be either an IDENTITY/BLOCKED/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;
|
||||
|
||||
@ -2043,19 +2040,16 @@ 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;
|
||||
unsigned int alloc_type = type & IOMMU_DOMAIN_ALLOC_FLAGS;
|
||||
|
||||
if (bus == NULL || bus->iommu_ops == NULL)
|
||||
return NULL;
|
||||
if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain)
|
||||
return ops->identity_domain;
|
||||
|
||||
if (alloc_type == IOMMU_DOMAIN_IDENTITY && bus->iommu_ops->identity_domain)
|
||||
return bus->iommu_ops->identity_domain;
|
||||
|
||||
domain = bus->iommu_ops->domain_alloc(alloc_type);
|
||||
domain = ops->domain_alloc(alloc_type);
|
||||
if (!domain)
|
||||
return NULL;
|
||||
|
||||
@ -2065,10 +2059,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);
|
||||
@ -2077,9 +2071,17 @@ 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)
|
||||
{
|
||||
return __iommu_domain_alloc(group_iommu_ops(group), 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);
|
||||
|
||||
@ -3239,21 +3241,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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user