From: Yuho Choi <oss.patchbox@gmail.com>
To: Tomasz Jeznach <tomasz.jeznach@linux.dev>,
Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>
Cc: Robin Murphy <robin.murphy@arm.com>,
Fangyu Yu <fangyu.yu@linux.alibaba.com>,
Zong Li <zong.li@sifive.com>, Lu Baolu <baolu.lu@linux.intel.com>,
Paul Walmsley <pjw@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>,
iommu@lists.linux.dev, linux-riscv@lists.infradead.org,
linux-kernel@vger.kernel.org, Yuho Choi <oss.patchbox@gmail.com>
Subject: [PATCH v1 2/2] iommu/riscv: Do not report a stalled command queue as completed
Date: Tue, 20 Oct 2026 01:34:24 -0400 [thread overview]
Message-ID: <20261020053435.1179054-6-oss.patchbox@gmail.com> (raw)
In-Reply-To: <20261020053435.1179054-4-oss.patchbox@gmail.com>
Since commit b2e5684558ed ("iommu/riscv: Stop polling when CQCSR reports
an error"), riscv_iommu_queue_wait() stops polling when CQCSR has cqmf,
cmd_to or cmd_ill set, but then returns 0 as if the waited-for command
had been executed. The hardware stops processing the queue at the
faulting command, so an IOFENCE.C queued behind it has not completed,
yet riscv_iommu_iotlb_sync() goes on to free the page table pages.
Return -EIO when the queue stopped before reaching the waited-for entry,
and keep the "command execution timeout" message for real timeouts; the
interrupt handler already reports the CQCSR error bits.
Fixes: b2e5684558ed ("iommu/riscv: Stop polling when CQCSR reports an error")
Assisted-by: LLM
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
---
This was found with a static analysis tool from ongoing, not yet
published research, and confirmed by code inspection. It has not been
reproduced on hardware or in an emulator.
drivers/iommu/riscv/iommu.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 816d50c0f508..2a95cb8c9e4c 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -371,15 +371,24 @@ static int riscv_iommu_queue_wait(struct riscv_iommu_queue *queue,
unsigned int cons = atomic_read(&queue->head);
unsigned int flags = RISCV_IOMMU_CQCSR_CQMF | RISCV_IOMMU_CQCSR_CMD_TO |
RISCV_IOMMU_CQCSR_CMD_ILL;
+ int ret;
/* Already processed by the consumer */
if ((int)(cons - index) > 0)
return 0;
/* Monitor consumer index */
- return readx_poll_timeout(riscv_iommu_queue_cons, queue, cons,
+ ret = readx_poll_timeout(riscv_iommu_queue_cons, queue, cons,
(riscv_iommu_readl(queue->iommu, queue->qcr) & flags) ||
(int)(cons - index) > 0, 0, timeout_us);
+ if (ret)
+ return ret;
+
+ /* The queue stopped on an error before it reached the item. */
+ if ((int)(cons - index) <= 0)
+ return -EIO;
+
+ return 0;
}
static int riscv_iommu_queue_wait_for_space(struct riscv_iommu_queue *queue,
@@ -531,7 +540,7 @@ static int riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
return 0;
ret = riscv_iommu_queue_wait(&iommu->cmdq, prod, timeout_us);
- if (ret)
+ if (ret == -ETIMEDOUT)
dev_err_once(iommu->dev,
"Hardware error: command execution timeout\n");
--
2.43.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: Yuho Choi <oss.patchbox@gmail.com>
To: Tomasz Jeznach <tomasz.jeznach@linux.dev>,
Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>
Cc: Robin Murphy <robin.murphy@arm.com>,
Fangyu Yu <fangyu.yu@linux.alibaba.com>,
Zong Li <zong.li@sifive.com>, Lu Baolu <baolu.lu@linux.intel.com>,
Paul Walmsley <pjw@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>,
iommu@lists.linux.dev, linux-riscv@lists.infradead.org,
linux-kernel@vger.kernel.org, Yuho Choi <oss.patchbox@gmail.com>
Subject: [PATCH v1 2/2] iommu/riscv: Do not report a stalled command queue as completed
Date: Tue, 20 Oct 2026 01:34:24 -0400 [thread overview]
Message-ID: <20261020053435.1179054-6-oss.patchbox@gmail.com> (raw)
In-Reply-To: <20261020053435.1179054-4-oss.patchbox@gmail.com>
Since commit b2e5684558ed ("iommu/riscv: Stop polling when CQCSR reports
an error"), riscv_iommu_queue_wait() stops polling when CQCSR has cqmf,
cmd_to or cmd_ill set, but then returns 0 as if the waited-for command
had been executed. The hardware stops processing the queue at the
faulting command, so an IOFENCE.C queued behind it has not completed,
yet riscv_iommu_iotlb_sync() goes on to free the page table pages.
Return -EIO when the queue stopped before reaching the waited-for entry,
and keep the "command execution timeout" message for real timeouts; the
interrupt handler already reports the CQCSR error bits.
Fixes: b2e5684558ed ("iommu/riscv: Stop polling when CQCSR reports an error")
Assisted-by: LLM
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
---
This was found with a static analysis tool from ongoing, not yet
published research, and confirmed by code inspection. It has not been
reproduced on hardware or in an emulator.
drivers/iommu/riscv/iommu.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 816d50c0f508..2a95cb8c9e4c 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -371,15 +371,24 @@ static int riscv_iommu_queue_wait(struct riscv_iommu_queue *queue,
unsigned int cons = atomic_read(&queue->head);
unsigned int flags = RISCV_IOMMU_CQCSR_CQMF | RISCV_IOMMU_CQCSR_CMD_TO |
RISCV_IOMMU_CQCSR_CMD_ILL;
+ int ret;
/* Already processed by the consumer */
if ((int)(cons - index) > 0)
return 0;
/* Monitor consumer index */
- return readx_poll_timeout(riscv_iommu_queue_cons, queue, cons,
+ ret = readx_poll_timeout(riscv_iommu_queue_cons, queue, cons,
(riscv_iommu_readl(queue->iommu, queue->qcr) & flags) ||
(int)(cons - index) > 0, 0, timeout_us);
+ if (ret)
+ return ret;
+
+ /* The queue stopped on an error before it reached the item. */
+ if ((int)(cons - index) <= 0)
+ return -EIO;
+
+ return 0;
}
static int riscv_iommu_queue_wait_for_space(struct riscv_iommu_queue *queue,
@@ -531,7 +540,7 @@ static int riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
return 0;
ret = riscv_iommu_queue_wait(&iommu->cmdq, prod, timeout_us);
- if (ret)
+ if (ret == -ETIMEDOUT)
dev_err_once(iommu->dev,
"Hardware error: command execution timeout\n");
--
2.43.0
next prev parent reply other threads:[~2026-10-20 5:35 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-20 5:34 [PATCH v1 0/2] iommu/riscv: Keep page table pages when IOTLB invalidation fails Yuho Choi
2026-10-20 5:34 ` Yuho Choi
2026-10-20 5:34 ` [PATCH v1 1/2] " Yuho Choi
2026-10-20 5:34 ` Yuho Choi
2026-10-20 5:34 ` Yuho Choi [this message]
2026-10-20 5:34 ` [PATCH v1 2/2] iommu/riscv: Do not report a stalled command queue as completed Yuho Choi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261020053435.1179054-6-oss.patchbox@gmail.com \
--to=oss.patchbox@gmail.com \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=baolu.lu@linux.intel.com \
--cc=fangyu.yu@linux.alibaba.com \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=robin.murphy@arm.com \
--cc=tomasz.jeznach@linux.dev \
--cc=will@kernel.org \
--cc=zong.li@sifive.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.