[PATCH 7/7] iommu/vt-d: Drop old iopf ref only after attach succeeds
From: Lu Baolu
Date: Wed Sep 09 2026 - 04:20:53 EST
identity_domain_attach_dev() currently removes the old domain’s iopf
reference before programming pass-through. If pass-through setup fails,
attach fails but the old domain is still effectively attached — now
with its IOPF ref already dropped.
This can undercount info->iopf_refcount and may disable iopf queue
handling while the old domain can still issue page requests.
Fix it by removing the old domain’s iopf reference only after
pass-through setup succeeds, matching other attach paths.
Fixes: 236dd58fabd2 ("iommu/vt-d: Fix iopf_refcount leak on RID domain replacement")
Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
---
drivers/iommu/intel/iommu.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 99cf6716f602..c1529be63650 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -3985,6 +3985,14 @@ static int identity_domain_attach_dev(struct iommu_domain *domain,
if (dev_is_real_dma_subdevice(dev))
return 0;
+ if (sm_supported(iommu))
+ ret = intel_pasid_setup_pass_through(iommu, dev, IOMMU_NO_PASID);
+ else
+ ret = device_setup_pass_through(dev);
+
+ if (ret)
+ return ret;
+
/*
* The identity domain has no iopf_handler, so no IOPF reference is
* taken for it. The reference held by the old domain must still be
@@ -3992,16 +4000,9 @@ static int identity_domain_attach_dev(struct iommu_domain *domain,
* not affect the IOPF reference count.
*/
iopf_for_domain_remove(old, dev);
+ info->domain_attached = true;
- if (sm_supported(iommu))
- ret = intel_pasid_setup_pass_through(iommu, dev, IOMMU_NO_PASID);
- else
- ret = device_setup_pass_through(dev);
-
- if (!ret)
- info->domain_attached = true;
-
- return ret;
+ return 0;
}
static int identity_domain_set_dev_pasid(struct iommu_domain *domain,
--
2.43.0