[PATCH v5 04/12] iommufd: Always pass iommu_attach_handle to iommu core

Yi Liu
2024-11-04T13:25:18Z

The iommu_attach_handle is optional in the RID attach/replace API and the
PASID attach APIs. But it is a mandatory argument for the PASID replace API.
Without it, the PASID replace path cannot get the old domain. Hence, the
PASID path (attach/replace) requires the attach handle. As iommufd is the
major user of the RID attach/replace with iommu_attach_handle, this also
makes the iommufd always pass the attach handle for the RID path as well.
This keeps the RID and PASID path much aligned.

Signed-off-by: Yi Liu <yi.l.liu@intel.com>
---
drivers/iommu/iommufd/fault.c | 12 ++++--------
drivers/iommu/iommufd/iommufd_private.h | 20 +++++++++++++++++---
2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index add94b044dc6..55418a067869 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -132,21 +132,17 @@ int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,

curr = iommufd_device_get_attach_handle(idev);

- if (hwpt->fault)
- ret = iommufd_dev_replace_handle(idev, hwpt, old);
- else
- ret = iommu_replace_group_handle(idev->igroup->group,
- hwpt->domain, NULL);
+ ret = iommufd_dev_replace_handle(idev, hwpt, old);
if (ret) {
if (iopf_on)
iommufd_fault_iopf_disable(idev);
return ret;
}

- if (curr) {
+ if (old->fault)
iommufd_auto_response_faults(old, curr);
- kfree(curr);
- }
+
+ kfree(curr);

if (iopf_off)
iommufd_fault_iopf_disable(idev);
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 66eb95063068..19870b08056e 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -512,28 +512,42 @@ static inline int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
if (hwpt->fault)
return iommufd_fault_domain_attach_dev(hwpt, idev);

- return iommu_attach_group(hwpt->domain, idev->igroup->group);
+ return iommufd_dev_attach_handle(hwpt, idev);
}

static inline void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
struct iommufd_device *idev)
{
+ struct iommufd_attach_handle *handle;
+
if (hwpt->fault) {
iommufd_fault_domain_detach_dev(hwpt, idev);
return;
}

- iommu_detach_group(hwpt->domain, idev->igroup->group);
+ handle = iommufd_device_get_attach_handle(idev);
+ iommu_detach_group_handle(hwpt->domain, idev->igroup->group);
+ kfree(handle);
}

static inline int iommufd_hwpt_replace_device(struct iommufd_device *idev,
struct iommufd_hw_pagetable *hwpt,
struct iommufd_hw_pagetable *old)
{
+ struct iommufd_attach_handle *curr;
+ int ret;
+
if (old->fault || hwpt->fault)
return iommufd_fault_domain_replace_dev(idev, hwpt, old);

- return iommu_group_replace_domain(idev->igroup->group, hwpt->domain);
+ curr = iommufd_device_get_attach_handle(idev);
+
+ ret = iommufd_dev_replace_handle(idev, hwpt, old);
+ if (ret)
+ return ret;
+
+ kfree(curr);
+ return 0;
}

#ifdef CONFIG_IOMMUFD_TEST
--
2.34.1