[PATCH] iommu/vt-d: release IRQ vector after request failure

Runyu Xiao posted 1 patch 1 day, 11 hours ago
drivers/iommu/intel/dmar.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
[PATCH] iommu/vt-d: release IRQ vector after request failure
Posted by Runyu Xiao 1 day, 11 hours ago
When request_irq() fails, iommu->irq remains set, so later teardown
attempts to free an IRQ that was never registered.

Release the reserved vector and clear iommu->irq on the failure path.

The failure path was reproduced with an x86_64 kernel under QEMU using a
q35 machine and an Intel IOMMU with interrupt remapping enabled. A
test-only failure injection makes request_irq() return -EBUSY after
dmar_alloc_hwirq() assigns a vector, then attempts to allocate the same
vector again.

On the unfixed kernel, the failed request leaves iommu->irq set and the
second allocation returns -EEXIST. With this change, iommu->irq is cleared
and the second allocation reuses the vector. The failure is deliberately
injected to exercise this error path and is not expected during normal
QEMU operation.

Fixes: 34742db8eaf9 ("iommu/vt-d: Refine the interfaces to create IRQ for DMAR unit")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
 drivers/iommu/intel/dmar.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index ba675b08c..d479e70c5 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -2098,8 +2098,11 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
 	}
 
 	ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu);
-	if (ret)
+	if (ret) {
 		pr_err("Can't request irq\n");
+		dmar_free_hwirq(iommu->irq);
+		iommu->irq = 0;
+	}
 	return ret;
 }
 
-- 
2.34.1