On Wed, Jul 1, 2026 at 7:23 PM Daniel Henrique Barboza
<[email protected]> wrote:
>
> We're hardcoding faulting type as READ, where it could very well be a
> write access, and we're not recording the faulting addr/iova.
>
> A note was added in the fault_type logic because I wasn't able to
> trivially handle a probable code repeitition it in this same patch.
> Something to do in a later date.
>
> Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3564
> Signed-off-by: Daniel Henrique Barboza <[email protected]>

Acked-by: Alistair Francis <[email protected]>

Alistair

> ---
>  hw/riscv/riscv-iommu.c | 29 +++++++++++++++++++++++------
>  1 file changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 70eede3f14..690c21289f 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -1330,6 +1330,7 @@ static void riscv_iommu_ctx_inval(RISCVIOMMUState *s, 
> GHFunc func,
>  /* Find or allocate translation context for a given {device_id, process_id} 
> */
>  static RISCVIOMMUContext *riscv_iommu_ctx(RISCVIOMMUState *s,
>                                            unsigned devid, unsigned 
> process_id,
> +                                          IOMMUAccessFlags perm, uint64_t 
> iova,
>                                            void **ref)
>  {
>      GHashTable *ctx_cache;
> @@ -1339,6 +1340,7 @@ static RISCVIOMMUContext 
> *riscv_iommu_ctx(RISCVIOMMUState *s,
>          .process_id = process_id,
>      };
>      unsigned mode = get_field(s->ddtp, RISCV_IOMMU_DDTP_MODE);
> +    uint32_t fault_type;
>
>      ctx_cache = g_hash_table_ref(s->ctx_cache);
>
> @@ -1381,8 +1383,21 @@ static RISCVIOMMUContext 
> *riscv_iommu_ctx(RISCVIOMMUState *s,
>      g_hash_table_unref(ctx_cache);
>      *ref = NULL;
>
> -    riscv_iommu_report_fault(s, ctx, RISCV_IOMMU_FQ_TTYPE_UADDR_RD,
> -                             fault, !!process_id, 0, 0);
> +    /*
> +     * TODO: (1) do we need to distinguish other fault types
> +     * for ctx fetching and (2) evaluate putting the 'fault_type'
> +     * logic inside riscv_iommu_report_fault() - there's at
> +     * least one other place (end of riscv_iommu_translate())
> +     * that does something similar.
> +     */
> +    if (perm & IOMMU_RO) {
> +        fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_RD;
> +    } else {
> +        fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_WR;
> +    }
> +
> +    riscv_iommu_report_fault(s, ctx, fault_type, fault,
> +                             !!process_id, iova, 0);
>
>      g_free(ctx);
>      return NULL;
> @@ -2128,6 +2143,8 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
>      uint64_t ctrl = riscv_iommu_reg_get64(s, RISCV_IOMMU_REG_TR_REQ_CTL);
>      unsigned devid = get_field(ctrl, RISCV_IOMMU_TR_REQ_CTL_DID);
>      unsigned pid = get_field(ctrl, RISCV_IOMMU_TR_REQ_CTL_PID);
> +    IOMMUAccessFlags perm = ctrl & RISCV_IOMMU_TR_REQ_CTL_NW
> +                            ? IOMMU_RO : IOMMU_RW;
>      RISCVIOMMUContext *ctx;
>      void *ref;
>
> @@ -2135,7 +2152,7 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
>          return;
>      }
>
> -    ctx = riscv_iommu_ctx(s, devid, pid, &ref);
> +    ctx = riscv_iommu_ctx(s, devid, pid, perm, iova, &ref);
>      if (ctx == NULL) {
>          riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_TR_RESPONSE,
>                                   RISCV_IOMMU_TR_RESPONSE_FAULT |
> @@ -2143,7 +2160,7 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
>      } else {
>          IOMMUTLBEntry iotlb = {
>              .iova = iova,
> -            .perm = ctrl & RISCV_IOMMU_TR_REQ_CTL_NW ? IOMMU_RO : IOMMU_RW,
> +            .perm = perm,
>              .addr_mask = ~0,
>              .target_as = NULL,
>          };
> @@ -2482,7 +2499,7 @@ static MemTxResult riscv_iommu_trap_write(void *opaque, 
> hwaddr addr,
>      /* FIXME: PCIe bus remapping for attached endpoints. */
>      devid |= s->bus << 8;
>
> -    ctx = riscv_iommu_ctx(s, devid, 0, &ref);
> +    ctx = riscv_iommu_ctx(s, devid, 0, IOMMU_RW, addr, &ref);
>      if (ctx == NULL) {
>          res = MEMTX_ACCESS_ERROR;
>      } else {
> @@ -2784,7 +2801,7 @@ static IOMMUTLBEntry 
> riscv_iommu_memory_region_translate(
>      };
>      uint32_t devid = riscv_iommu_space_devid(as);
>
> -    ctx = riscv_iommu_ctx(as->iommu, devid, iommu_idx, &ref);
> +    ctx = riscv_iommu_ctx(as->iommu, devid, iommu_idx, flag, addr, &ref);
>      if (ctx == NULL) {
>          /* Translation disabled or invalid. */
>          iotlb.addr_mask = 0;
> --
> 2.43.0
>
>

Reply via email to