Re: [PATCH v10 08/12] iommu/sva: Refactoring iommu_sva_bind/unbind_device()

From: Baolu Lu
Date: Mon Jul 25 2022 - 05:33:18 EST


Hi Jean,

On 2022/7/25 15:39, Jean-Philippe Brucker wrote:
On Sun, Jul 24, 2022 at 09:48:15PM +0800, Baolu Lu wrote:
/*
* iommu_detach_device_pasid() - Detach the domain from pasid of device
* @domain: the iommu domain.
* @dev: the attached device.
* @pasid: the pasid of the device.
*
* The @domain must have been attached to @pasid of the @dev with
* iommu_detach_device_pasid().
*/
void iommu_detach_device_pasid(struct iommu_domain *domain, struct device
*dev,
ioasid_t pasid)
{
struct iommu_group *group = iommu_group_get(dev);
struct group_pasid *param;

mutex_lock(&group->mutex);
domain->ops->set_dev_pasid(group->blocking_domain, dev, pasid);
Please also pass the old domain to this detach() function, so that the
IOMMU driver doesn't have to keep track of them internally.

The iommu core provides the interface to retrieve attached domain with a
{device, pasid} pair. Therefore in the smmuv3 driver, the set_dev_pasid
could do like this:

+static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
+ struct device *dev, ioasid_t id)
+{
+ int ret = 0;
+ struct mm_struct *mm;
+ struct iommu_sva *handle;
+
+ /*
+ * Detach the domain if a blocking domain is set. Check the
+ * right domain type once the IOMMU driver supports a real
+ * blocking domain.
+ */
+ if (!domain || domain->type == IOMMU_DOMAIN_UNMANAGED) {
+ struct pasid_iommu *param;
+
+ param = iommu_device_pasid_param(dev, id);
+ if (!param || !param->domain)
+ return -EINVAL;
+ arm_smmu_sva_block_dev_pasid(param->domain, dev, id);
+
+ return 0;
+ }
+
+ mm = domain->mm;
+ mutex_lock(&sva_lock);
+ handle = __arm_smmu_sva_bind(dev, mm);
+ if (IS_ERR(handle))
+ ret = PTR_ERR(handle);
+ mutex_unlock(&sva_lock);
+
+ return ret;
+}

The check of "(!domain || domain->type == IOMMU_DOMAIN_UNMANAGED)" looks
odd, but could get cleaned up after a real blocking domain is added.
Then, we can simply check "domain->type == IOMMU_DOMAIN_BLOCKING".

In addition to clearing contexts, detach() also needs to invalidate TLBs,
and for that the SMMU driver needs to know the old ASID (!= PASID) that
was used by the context descriptor.

Best regards,
baolu