[PATCH] hw/riscv: riscv-iommu: Re-process command queue after clearing CMD_ILL

Jay Chang posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260106080520.28711-1-jay.chang@sifive.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
hw/riscv/riscv-iommu.c | 10 ++++++++++
1 file changed, 10 insertions(+)
[PATCH] hw/riscv: riscv-iommu: Re-process command queue after clearing CMD_ILL
Posted by Jay Chang 1 month ago
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, the software error recovery sequence:

  1. Read the head pointer
  2. Software has two options:
     - Option 1: Set tail = head to re-start from an empty queue
     - Option 2: Overwrite the illegal command with a valid one
  3. Re-enable the command queue by writing 1 to cqcsr.cmd_ill

  "At this point, IOMMU will start working on the first command
   in the queue."

Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Frank Chang <frank.chang@sifive.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 b46b337375..e89a262a63 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -1992,6 +1992,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
Re: [PATCH] hw/riscv: riscv-iommu: Re-process command queue after clearing CMD_ILL
Posted by Daniel Henrique Barboza 1 month ago

On 1/6/26 5:05 AM, 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, the software error recovery sequence:
> 
>    1. Read the head pointer
>    2. Software has two options:
>       - Option 1: Set tail = head to re-start from an empty queue
>       - Option 2: Overwrite the illegal command with a valid one
>    3. Re-enable the command queue by writing 1 to cqcsr.cmd_ill
> 
>    "At this point, IOMMU will start working on the first command
>     in the queue."
> 
> 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 b46b337375..e89a262a63 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -1992,6 +1992,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)