hw/riscv/riscv-iommu.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
When software clears CMD_ILL or CQMF error bits by writing 1 to CQCSR,
the IOMMU should re-check the command queue and continue processing
pending commands if head != tail.
Per RISC-V IOMMU specification :
If command-queue access leads to a memory fault then the
command-queue-memory-fault bit is set to 1 and the commandqueue
stalls until this bit is cleared. To re-enable command
processing, software should clear this bit by writing 1.
Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
hw/riscv/riscv-iommu.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index 5bc2472a83..1b8a8e9ef2 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -2034,6 +2034,16 @@ static void riscv_iommu_process_cq_control(RISCVIOMMUState *s)
}
riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_CQCSR, ctrl_set, ctrl_clr);
+
+ /*
+ * After clearing error bits (CMD_ILL, CQMF), if queue is still active,
+ * re-process pending command.
+ */
+ ctrl_set = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_CQCSR);
+ if ((ctrl_set & RISCV_IOMMU_CQCSR_CQON) &&
+ !(ctrl_set & (RISCV_IOMMU_CQCSR_CMD_ILL | RISCV_IOMMU_CQCSR_CQMF))) {
+ riscv_iommu_process_cq_tail(s);
+ }
}
static void riscv_iommu_process_fq_control(RISCVIOMMUState *s)
--
2.48.1
On Mon, May 18, 2026 at 5:03 PM Jay Chang <jay.chang@sifive.com> wrote:
>
> When software clears CMD_ILL or CQMF error bits by writing 1 to CQCSR,
> the IOMMU should re-check the command queue and continue processing
> pending commands if head != tail.
>
> Per RISC-V IOMMU specification :
> If command-queue access leads to a memory fault then the
> command-queue-memory-fault bit is set to 1 and the commandqueue
> stalls until this bit is cleared. To re-enable command
> processing, software should clear this bit by writing 1.
>
> Signed-off-by: Jay Chang <jay.chang@sifive.com>
> Reviewed-by: Frank Chang <frank.chang@sifive.com>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Thanks!
Applied to riscv-to-apply.next
Alistair
> ---
> hw/riscv/riscv-iommu.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 5bc2472a83..1b8a8e9ef2 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -2034,6 +2034,16 @@ static void riscv_iommu_process_cq_control(RISCVIOMMUState *s)
> }
>
> riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_CQCSR, ctrl_set, ctrl_clr);
> +
> + /*
> + * After clearing error bits (CMD_ILL, CQMF), if queue is still active,
> + * re-process pending command.
> + */
> + ctrl_set = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_CQCSR);
> + if ((ctrl_set & RISCV_IOMMU_CQCSR_CQON) &&
> + !(ctrl_set & (RISCV_IOMMU_CQCSR_CMD_ILL | RISCV_IOMMU_CQCSR_CQMF))) {
> + riscv_iommu_process_cq_tail(s);
> + }
> }
>
> static void riscv_iommu_process_fq_control(RISCVIOMMUState *s)
> --
> 2.48.1
>
>
On 5/18/2026 3:01 PM, Jay Chang wrote:
> When software clears CMD_ILL or CQMF error bits by writing 1 to CQCSR,
> the IOMMU should re-check the command queue and continue processing
> pending commands if head != tail.
>
> Per RISC-V IOMMU specification :
> If command-queue access leads to a memory fault then the
> command-queue-memory-fault bit is set to 1 and the commandqueue
> stalls until this bit is cleared. To re-enable command
> processing, software should clear this bit by writing 1.
>
> Signed-off-by: Jay Chang <jay.chang@sifive.com>
> Reviewed-by: Frank Chang <frank.chang@sifive.com>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Thanks,
Nutty
> ---
> hw/riscv/riscv-iommu.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 5bc2472a83..1b8a8e9ef2 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -2034,6 +2034,16 @@ static void riscv_iommu_process_cq_control(RISCVIOMMUState *s)
> }
>
> riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_CQCSR, ctrl_set, ctrl_clr);
> +
> + /*
> + * After clearing error bits (CMD_ILL, CQMF), if queue is still active,
> + * re-process pending command.
> + */
> + ctrl_set = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_CQCSR);
> + if ((ctrl_set & RISCV_IOMMU_CQCSR_CQON) &&
> + !(ctrl_set & (RISCV_IOMMU_CQCSR_CMD_ILL | RISCV_IOMMU_CQCSR_CQMF))) {
> + riscv_iommu_process_cq_tail(s);
> + }
> }
>
> static void riscv_iommu_process_fq_control(RISCVIOMMUState *s)
© 2016 - 2026 Red Hat, Inc.