Commit 6caeb33f authored by Lu Baolu's avatar Lu Baolu Committed by Joerg Roedel

iommu: Add set_platform_dma_ops iommu ops

When VFIO finishes assigning a device to user space and calls
iommu_group_release_dma_owner() to return the device to kernel, the IOMMU
core will attach the default domain to the device. Unfortunately, some
IOMMU drivers don't support default domain, hence in the end, the core
calls .detach_dev instead.

This adds set_platform_dma_ops iommu ops to make it clear that what it
does is returning control back to the platform DMA ops.
Suggested-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20230110025408.667767-3-baolu.lu@linux.intel.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 1b932ced
...@@ -2163,6 +2163,16 @@ static int iommu_group_do_detach_device(struct device *dev, void *data) ...@@ -2163,6 +2163,16 @@ static int iommu_group_do_detach_device(struct device *dev, void *data)
return 0; return 0;
} }
static int iommu_group_do_set_platform_dma(struct device *dev, void *data)
{
const struct iommu_ops *ops = dev_iommu_ops(dev);
if (!WARN_ON(!ops->set_platform_dma_ops))
ops->set_platform_dma_ops(dev);
return 0;
}
static int __iommu_group_set_domain(struct iommu_group *group, static int __iommu_group_set_domain(struct iommu_group *group,
struct iommu_domain *new_domain) struct iommu_domain *new_domain)
{ {
...@@ -2177,10 +2187,20 @@ static int __iommu_group_set_domain(struct iommu_group *group, ...@@ -2177,10 +2187,20 @@ static int __iommu_group_set_domain(struct iommu_group *group,
* platform specific behavior. * platform specific behavior.
*/ */
if (!new_domain) { if (!new_domain) {
if (WARN_ON(!group->domain->ops->detach_dev)) struct group_device *grp_dev;
return -EINVAL;
grp_dev = list_first_entry(&group->devices,
struct group_device, list);
if (dev_iommu_ops(grp_dev->dev)->set_platform_dma_ops)
__iommu_group_for_each_dev(group, NULL,
iommu_group_do_set_platform_dma);
else if (group->domain->ops->detach_dev)
__iommu_group_for_each_dev(group, group->domain, __iommu_group_for_each_dev(group, group->domain,
iommu_group_do_detach_device); iommu_group_do_detach_device);
else
WARN_ON_ONCE(1);
group->domain = NULL; group->domain = NULL;
return 0; return 0;
} }
......
...@@ -228,6 +228,9 @@ struct iommu_iotlb_gather { ...@@ -228,6 +228,9 @@ struct iommu_iotlb_gather {
* @release_device: Remove device from 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 * @probe_finalize: Do final setup work after the device is added to an IOMMU
* group and attached to the groups domain * group and attached to the groups domain
* @set_platform_dma_ops: Returning control back to the platform DMA ops. This op
* is to support old IOMMU drivers, new drivers should use
* default domains, and the common IOMMU DMA ops.
* @device_group: find iommu group for a particular device * @device_group: find iommu group for a particular device
* @get_resv_regions: Request list of reserved regions for a device * @get_resv_regions: Request list of reserved regions for a device
* @of_xlate: add OF master IDs to iommu grouping * @of_xlate: add OF master IDs to iommu grouping
...@@ -256,6 +259,7 @@ struct iommu_ops { ...@@ -256,6 +259,7 @@ struct iommu_ops {
struct iommu_device *(*probe_device)(struct device *dev); struct iommu_device *(*probe_device)(struct device *dev);
void (*release_device)(struct device *dev); void (*release_device)(struct device *dev);
void (*probe_finalize)(struct device *dev); void (*probe_finalize)(struct device *dev);
void (*set_platform_dma_ops)(struct device *dev);
struct iommu_group *(*device_group)(struct device *dev); struct iommu_group *(*device_group)(struct device *dev);
/* Request/Free a list of reserved regions for a device */ /* Request/Free a list of reserved regions for a device */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment