@@ -458,6 +458,7 @@ static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
static void iommu_default_domain_free(struct iommu_domain *domain)
{
+ iommu_put_dma_cookie(domain);
iommu_domain_free(domain);
}
@@ -2028,7 +2029,6 @@ void iommu_domain_free(struct iommu_domain *domain)
{
if (domain->type == IOMMU_DOMAIN_SVA)
mmdrop(domain->mm);
- iommu_put_dma_cookie(domain);
if (domain->ops->free)
domain->ops->free(domain);
}
@@ -2271,6 +2271,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
if (!iommu_attach_group(d->domain,
group->iommu_group)) {
list_add(&group->next, &d->group_list);
+ iommu_put_msi_cookie(domain->domain);
iommu_domain_free(domain->domain);
kfree(domain);
goto done;
@@ -2316,6 +2317,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
out_detach:
iommu_detach_group(domain->domain, group->iommu_group);
out_domain:
+ iommu_put_msi_cookie(domain->domain);
iommu_domain_free(domain->domain);
vfio_iommu_iova_free(&iova_copy);
vfio_iommu_resv_free(&group_resv_regions);
@@ -2496,6 +2498,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
vfio_iommu_unmap_unpin_reaccount(iommu);
}
}
+ iommu_put_msi_cookie(domain->domain);
iommu_domain_free(domain->domain);
list_del(&domain->next);
kfree(domain);
@@ -2567,6 +2570,7 @@ static void vfio_release_domain(struct vfio_domain *domain)
kfree(group);
}
+ iommu_put_msi_cookie(domain->domain);
iommu_domain_free(domain->domain);
}
Not all domain owners need the iova_cookie. To isolate the iova_cookie to the domain that actually owns it, request the owner to put the DMA or MSI cookie explicitly, instead of calling the put() in the common path of the iommu_domain_free(). Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> --- drivers/iommu/iommu.c | 2 +- drivers/vfio/vfio_iommu_type1.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-)