[PATCH] iommu/vt-d: Fix IQE handling to cover all descriptors in submission range
Guanghui Feng <[email protected]> Wed, 5 Aug 2026 12:20:12 +0800
| Newsgroups | dev.linux.lists.iommu,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Currently, qi_check_fault() only handles IQE (Invalidation Queue Error) when the faulting descriptor index exactly matches the first descriptor of the current submission (head == index). This is too restrictive in multi-descriptor submissions where the error could occur at any descriptor within the batch. If the IQE is triggered by a descriptor that belongs to the current submission but is not at the starting index, the function returns 0 without clearing the IQE fault status. Since hardware stops fetching new descriptors until IQE is cleared, this leads to an indefinite wait on the wait descriptor completion - effectively a deadlock. Fix this by expanding the IQE handling condition to cover all descriptors within the circular range [index, wait_index]. Use explicit bounds checking that properly handles the wrap-around case of the circular queue. Signed-off-by: Guanghui Feng <[email protected]> Signed-off-by: bikuan.zbk <[email protected]> --- drivers/iommu/intel/dmar.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c index 767ec092accd..8ae513593406 100644 --- a/drivers/iommu/intel/dmar.c +++ b/drivers/iommu/intel/dmar.c @@ -1290,8 +1290,13 @@ static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index) * is cleared. */ if (fault & DMA_FSTS_IQE) { + int head_idx; + head = readl(iommu->reg + DMAR_IQH_REG); - if ((head >> shift) == index) { + head_idx = head >> shift; + if (index <= wait_index ? + (head_idx >= index && head_idx <= wait_index) : + (head_idx >= index || head_idx <= wait_index)) { struct qi_desc *desc = qi->desc + head; /* -- 2.43.7