@@ -146,35 +146,30 @@ void iommufd_fault_domain_detach_dev(struct iommufd_hw_pagetable *hwpt,
kfree(handle);
}
-static int __fault_domain_replace_dev(struct iommufd_device *idev,
- struct iommufd_hw_pagetable *hwpt,
- struct iommufd_hw_pagetable *old)
+/* Caller to free the old iommufd_attach_handle */
+static struct iommufd_attach_handle *
+__fault_domain_replace_dev(struct iommufd_device *idev,
+ struct iommufd_hw_pagetable *hwpt,
+ struct iommufd_hw_pagetable *old)
{
- struct iommufd_attach_handle *handle, *curr = NULL;
+ struct iommufd_attach_handle *handle, *curr;
int ret;
- if (old->fault)
- curr = iommufd_device_get_attach_handle(idev);
-
- if (hwpt->fault) {
- handle = kzalloc(sizeof(*handle), GFP_KERNEL);
- if (!handle)
- return -ENOMEM;
+ curr = iommufd_device_get_attach_handle(idev);
- handle->idev = idev;
- ret = iommu_replace_group_handle(idev->igroup->group,
- hwpt->domain, &handle->handle);
- } else {
- ret = iommu_replace_group_handle(idev->igroup->group,
- hwpt->domain, NULL);
- }
+ handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+ if (!handle)
+ return ERR_PTR(-ENOMEM);
- if (!ret && curr) {
- iommufd_auto_response_faults(old, curr);
- kfree(curr);
+ handle->idev = idev;
+ ret = iommu_replace_group_handle(idev->igroup->group,
+ hwpt->domain, &handle->handle);
+ if (ret) {
+ kfree(handle);
+ return ERR_PTR(ret);
}
- return ret;
+ return curr;
}
int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,
@@ -183,6 +178,7 @@ int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,
{
bool iopf_off = !hwpt->fault && old->fault;
bool iopf_on = hwpt->fault && !old->fault;
+ struct iommufd_attach_handle *curr = NULL;
int ret;
if (iopf_on) {
@@ -191,13 +187,25 @@ int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,
return ret;
}
- ret = __fault_domain_replace_dev(idev, hwpt, old);
+ if (hwpt->fault) {
+ curr = __fault_domain_replace_dev(idev, hwpt, old);
+ ret = IS_ERR(curr) ? PTR_ERR(curr) : 0;
+ } else {
+ ret = iommu_replace_group_handle(idev->igroup->group,
+ hwpt->domain, NULL);
+ }
+
if (ret) {
if (iopf_on)
iommufd_fault_iopf_disable(idev);
return ret;
}
+ if (curr) {
+ iommufd_auto_response_faults(old, curr);
+ kfree(curr);
+ }
+
if (iopf_off)
iommufd_fault_iopf_disable(idev);
There is a wrapper of iommu_attach_group_handle(), so making a wrapper for iommu_replace_group_handle() for further code refactor. No functional change intended. Signed-off-by: Yi Liu <yi.l.liu@intel.com> --- drivers/iommu/iommufd/fault.c | 54 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 23 deletions(-)