Re: [PATCH v4 2/9] iommu: Replace sva_iommu with iommu_attach_handle

Baolu Lu
2024-04-06T06:10:42Z

On 4/3/24 7:59 PM, Jason Gunthorpe wrote:
> On Wed, Apr 03, 2024 at 09:15:12AM +0800, Lu Baolu wrote:
>> + /* A bond already exists, just take a reference`. */
>> + handle = iommu_attach_handle_get(group, iommu_mm->pasid);
>> + if (handle) {
>> + mutex_unlock(&iommu_sva_lock);
>> + return handle;
>> }
> At least in this context this is not enough we need to ensure that the
> domain on the PASID is actually an SVA domain and it was installed by
> this mechanism, not an iommufd domain for instance.
>
> ie you probably need a type field in the iommu_attach_handle to tell
> what the priv is.
>
> Otherwise this seems like a great idea!

Yes, you are right. For the SVA case, I will add the following changes.
The IOMMUFD path will also need such enhancement. I will update it in
the next version.

diff --git a/drivers/iommu/iommu-priv.h b/drivers/iommu/iommu-priv.h
index 08c0667cef54..9aee70f87a21 100644
--- a/drivers/iommu/iommu-priv.h
+++ b/drivers/iommu/iommu-priv.h
@@ -28,9 +28,22 @@ void iommu_device_unregister_bus(struct iommu_device
*iommu,
const struct bus_type *bus,
struct notifier_block *nb);

+enum attach_handle_type {
+ ATTACH_HANDLE_TYPE_DEFAULT = 0,
+ ATTACH_HANDLE_TYPE_SVA,
+ ATTACH_HANDLE_TYPE_IOMMUFD,
+};
+
struct iommu_attach_handle {
struct iommu_domain *domain;
refcount_t users;
+
+ /*
+ * Set by the attach interface callers. The type field could be used
+ * by the caller to identify whether the priv field was installed by
+ * them.
+ */
+ enum attach_handle_type type;
void *priv;
};

diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index c66cf26137bf..3eb664cc3f3a 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -90,7 +90,11 @@ struct iommu_attach_handle
*iommu_sva_bind_device(struct device *dev, struct mm_
handle = iommu_attach_handle_get(group, iommu_mm->pasid);
if (handle) {
mutex_unlock(&iommu_sva_lock);
- return handle;
+ if (handle->type == ATTACH_HANDLE_TYPE_SVA)
+ return handle;
+
+ iommu_attach_handle_put(handle);
+ return ERR_PTR(-EBUSY);
}

/* Search for an existing domain. */
@@ -118,6 +122,7 @@ struct iommu_attach_handle
*iommu_sva_bind_device(struct device *dev, struct mm_
out:
handle = iommu_attach_handle_get(group, iommu_mm->pasid);
mutex_unlock(&iommu_sva_lock);
+ handle->type = ATTACH_HANDLE_TYPE_SVA;
handle->priv = dev;

return handle;

Best regards,
baolu