Skip to content

Commit

Permalink
iommu: Revert pasid attachment only for the devices that have succeeded
Browse files Browse the repository at this point in the history
There is no error hanlding now in __iommu_set_group_pasid(), it relies on
the caller to loop all the devices to revert pasid attachment if the
__iommu_set_group_pasid() failed. This is not perfect for the multi-device
groups. It's better to handle the error within __iommu_set_group_pasid(),
and only revert the devices that have succeeded.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
  • Loading branch information
yiliu1765 committed Mar 21, 2024
1 parent 7493b60 commit bb83270
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions drivers/iommu/iommu.c
Expand Up @@ -3306,15 +3306,25 @@ EXPORT_SYMBOL_GPL(iommu_group_dma_owner_claimed);
static int __iommu_set_group_pasid(struct iommu_domain *domain,
struct iommu_group *group, ioasid_t pasid)
{
struct group_device *device;
int ret = 0;
struct group_device *device, *last_gdev;
int ret;

for_each_group_device(group, device) {
ret = domain->ops->set_dev_pasid(domain, device->dev, pasid);
if (ret)
break;
goto err_revert;
}

return 0;

err_revert:
last_gdev = device;
for_each_group_device(group, device) {
if (device == last_gdev)
break;
dev_iommu_ops(device->dev)->remove_dev_pasid(device->dev,
pasid);
}
return ret;
}

Expand Down Expand Up @@ -3363,10 +3373,8 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
}

ret = __iommu_set_group_pasid(domain, group, pasid);
if (ret) {
__iommu_remove_group_pasid(group, pasid);
if (ret)
xa_erase(&group->pasid_array, pasid);
}
out_unlock:
mutex_unlock(&group->mutex);
return ret;
Expand Down

0 comments on commit bb83270

Please sign in to comment.