[PATCH v4 01/27] iommu/arm-smmu-v3: Check that the RID domain is S1 in SVA
Jason Gunthorpe
jgg at nvidia.com
Tue Jan 30 11:03:58 PST 2024
On Tue, Jan 30, 2024 at 05:11:36PM +0000, Shameerali Kolothum Thodi wrote:
> >
> > > > + if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
> > > > + return -ENODEV;
> > >
> > > I think we need to do the above checks in
> > arm_smmu_sva_remove_dev_pasid()
> > > as well.
> >
> > The core won't call that unless a PASID is already attached, meaning
> > we already passed the above check in bind. So it shouldn't need to be
> > duplicated.
>
> I think it does in the error path. See __iommu_set_group_pasid() call.
> I haven't tested what happens if that returns error because of identity
> domain and then __iommu_remove_group_pasid() is called.
You are correct, but this is a problem in the core code :(
Driver should not have to deal with this unbalance. A set/remove
pairing should be enforced by the core.
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3481,15 +3481,24 @@ 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 *last_gdev;
struct group_device *device;
int ret = 0;
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;
}
@@ -3538,10 +3547,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;
> So as an exported function, still think it is better to check for domain
> type before accessing smmu_domain there.
After part 2 the remove path doesn't touch the RID so I prefer to
leave it in part 1 and it will be fully safe in part 2. It is just
more code that part 2 has to remove.
Thanks,
Jason
More information about the linux-arm-kernel
mailing list