All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] iommu/vt-d: Fix IQE handling to cover all descriptors in submission range
@ 2026-08-05  4:20 Guanghui Feng
  2026-08-20  3:09 ` Baolu Lu
  0 siblings, 1 reply; 4+ messages in thread
From: Guanghui Feng @ 2026-08-05  4:20 UTC (permalink / raw)
  To: dwmw2, baolu.lu, joro, will, robin.murphy; +Cc: iommu, linux-kernel

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 <guanghuifeng@linux.alibaba.com>
Signed-off-by: bikuan.zbk <bikuan.zbk@alibaba-inc.com>
---
 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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] iommu/vt-d: Fix IQE handling to cover all descriptors in submission range
  2026-08-05  4:20 [PATCH] iommu/vt-d: Fix IQE handling to cover all descriptors in submission range Guanghui Feng
@ 2026-08-20  3:09 ` Baolu Lu
  2026-08-20 14:47   ` Guanghui Feng
  0 siblings, 1 reply; 4+ messages in thread
From: Baolu Lu @ 2026-08-20  3:09 UTC (permalink / raw)
  To: Guanghui Feng, dwmw2, joro, will, robin.murphy; +Cc: iommu, linux-kernel

On 8/5/26 12:20, Guanghui Feng wrote:
> 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.
> 

Fixes: 8a1d82462540 ("iommu/vt-d: Multiple descriptors per 
qi_submit_sync()")
Cc: stable@vger.kernel.org

> Signed-off-by: Guanghui Feng <guanghuifeng@linux.alibaba.com>
> Signed-off-by: bikuan.zbk <bikuan.zbk@alibaba-inc.com>
> ---
>   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;

How about adding a brief comment like this?

	/*
	 * The faulting descriptor can be anywhere within the current
	 * submission's range [index, wait_index]. Since the queue is
	 * circular, this submission may wrap around QI_LENGTH
	 * (index > wait_index in that case), so check both the
	 * non-wrapped and wrapped cases of the range.
	 */

> +		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;
>   
>   			/*

Otherwise, this looks good to me.

Thanks,
baolu

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] iommu/vt-d: Fix IQE handling to cover all descriptors in submission range
  2026-08-20  3:09 ` Baolu Lu
@ 2026-08-20 14:47   ` Guanghui Feng
  2026-08-20 19:37     ` Samiullah Khawaja
  0 siblings, 1 reply; 4+ messages in thread
From: Guanghui Feng @ 2026-08-20 14:47 UTC (permalink / raw)
  To: baolu.lu
  Cc: dwmw2, guanghuifeng, iommu, joro, linux-kernel, robin.murphy,
	will, bikuan . zbk

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 <guanghuifeng@linux.alibaba.com>
Signed-off-by: bikuan.zbk <bikuan.zbk@alibaba-inc.com>
---
 drivers/iommu/intel/dmar.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index ba675b08cd20..ecc95af06f61 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -1366,8 +1366,21 @@ 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;
+
+		/*
+		 * The faulting descriptor can be anywhere within the current
+		 * submission's range [index, wait_index]. Since the queue is
+		 * circular, this submission may wrap around QI_LENGTH
+		 * (index > wait_index in that case), so check both the
+		 * non-wrapped and wrapped cases of the range.
+		 */ 
+		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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] iommu/vt-d: Fix IQE handling to cover all descriptors in submission range
  2026-08-20 14:47   ` Guanghui Feng
@ 2026-08-20 19:37     ` Samiullah Khawaja
  0 siblings, 0 replies; 4+ messages in thread
From: Samiullah Khawaja @ 2026-08-20 19:37 UTC (permalink / raw)
  To: Guanghui Feng
  Cc: baolu.lu, dwmw2, iommu, joro, linux-kernel, robin.murphy, will,
	bikuan . zbk

On Thu, Aug 20, 2026 at 10:47:41PM +0800, Guanghui Feng wrote:
>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 <guanghuifeng@linux.alibaba.com>
>Signed-off-by: bikuan.zbk <bikuan.zbk@alibaba-inc.com>
>---
> drivers/iommu/intel/dmar.c | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
>index ba675b08cd20..ecc95af06f61 100644
>--- a/drivers/iommu/intel/dmar.c
>+++ b/drivers/iommu/intel/dmar.c
>@@ -1366,8 +1366,21 @@ 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;
>+
>+		/*
>+		 * The faulting descriptor can be anywhere within the current
>+		 * submission's range [index, wait_index]. Since the queue is
>+		 * circular, this submission may wrap around QI_LENGTH
>+		 * (index > wait_index in that case), so check both the
>+		 * non-wrapped and wrapped cases of the range.
>+		 */
>+		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
>
>

Reviewed-by: Samiullah Khawaja <skhawaja@google.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-20 19:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05  4:20 [PATCH] iommu/vt-d: Fix IQE handling to cover all descriptors in submission range Guanghui Feng
2026-08-20  3:09 ` Baolu Lu
2026-08-20 14:47   ` Guanghui Feng
2026-08-20 19:37     ` Samiullah Khawaja

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.