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

From: Baolu Lu
Date: Sat Apr 06 2024 - 02:11:41 EST


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