[PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()

Daniel Henrique Barboza posted 1 patch 3 weeks, 4 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260701092241.307801-1-daniel.barboza@oss.qualcomm.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu.zevorn@gmail.com>
hw/riscv/riscv-iommu.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
[PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Daniel Henrique Barboza 3 weeks, 4 days ago
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 <daniel.barboza@oss.qualcomm.com>
---
 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
Re: [PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Michael Tokarev 2 weeks, 1 day ago
On 7/1/26 12:22, Daniel Henrique Barboza 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 <daniel.barboza@oss.qualcomm.com>
> ---
>   hw/riscv/riscv-iommu.c | 29 +++++++++++++++++++++++------
>   1 file changed, 23 insertions(+), 6 deletions(-)

For the stable qemu series (currently 10.0.x-LTS and 11.0.x), in order
to pick this commit, I also picked v11.0.0-1212-gca7bac51e04
"hw/riscv/riscv-iommu: Avoid caching PCI device IDs" by Chengbo Gao
(Cc'ed) - because it touched the same code and there's a merge conflict.
I can edit this patch ("set ftype and iova in riscv_iommu_ctx()") instead,
but it felt that ca7bac51e04 is also a good pick for the stable series.

Additionally for 10.0.x-LTS series, I also picked 2 more commits:

v10.2.0-323-g15406cc593a "hw/riscv: riscv-iommu: Don't look up DDT cache
  in Off and Bare modes" by Frank Chang (Cc'ed), which avoids a merge
  conflict and also looks like a (maybe missing) bugfix.

v10.2.0-312-gc497ef6739c "hw/riscv/riscv-iommu: Fix MemoryRegion owner"
  by Akihiko Odaki, which I spotted when looking for the history of
  changes, and which looked like an obvious bugfix.

Hopefully this is okay.  Unfortunately even the simpler changes brings
up quite a lot of missing fixes just by a chance - this means that we
either not doing a good job keeping stable series up to date (by marking
commits fixing stuff for-stable), or we should not try fixing stuff in
previous series for a too-fast-moving target.

I'm sorry I'm bringing up this more general question in a very narrow
context of this particular fix (which might not even be important
enough).  Maybe I should discuss this separately.  Overall, I'm
having some.. issues with riscv pullreqs in context of stable series,
it's always more time-consuming to handle these and a bit more difficult
to decide what is imortant and what can be skipped.

Thanks,

/mjt
Re: [PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Alistair Francis 1 week, 6 days ago
On Sat, 2026-07-11 at 10:47 +0300, Michael Tokarev wrote:
> On 7/1/26 12:22, Daniel Henrique Barboza 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
> > <daniel.barboza@oss.qualcomm.com>
> > ---
> >   hw/riscv/riscv-iommu.c | 29 +++++++++++++++++++++++------
> >   1 file changed, 23 insertions(+), 6 deletions(-)
> 
> For the stable qemu series (currently 10.0.x-LTS and 11.0.x), in
> order
> to pick this commit, I also picked v11.0.0-1212-gca7bac51e04
> "hw/riscv/riscv-iommu: Avoid caching PCI device IDs" by Chengbo Gao
> (Cc'ed) - because it touched the same code and there's a merge
> conflict.
> I can edit this patch ("set ftype and iova in riscv_iommu_ctx()")
> instead,
> but it felt that ca7bac51e04 is also a good pick for the stable
> series.
> 
> Additionally for 10.0.x-LTS series, I also picked 2 more commits:
> 
> v10.2.0-323-g15406cc593a "hw/riscv: riscv-iommu: Don't look up DDT
> cache
>   in Off and Bare modes" by Frank Chang (Cc'ed), which avoids a merge
>   conflict and also looks like a (maybe missing) bugfix.
> 
> v10.2.0-312-gc497ef6739c "hw/riscv/riscv-iommu: Fix MemoryRegion
> owner"
>   by Akihiko Odaki, which I spotted when looking for the history of
>   changes, and which looked like an obvious bugfix.

Thanks for that, those both look like good candidates.

> 
> Hopefully this is okay.  Unfortunately even the simpler changes
> brings
> up quite a lot of missing fixes just by a chance - this means that we
> either not doing a good job keeping stable series up to date (by
> marking
> commits fixing stuff for-stable), or we should not try fixing stuff
> in
> previous series for a too-fast-moving target.

Probably both

> 
> I'm sorry I'm bringing up this more general question in a very narrow
> context of this particular fix (which might not even be important
> enough).  Maybe I should discuss this separately.  Overall, I'm
> having some.. issues with riscv pullreqs in context of stable series,
> it's always more time-consuming to handle these and a bit more
> difficult
> to decide what is imortant and what can be skipped.

Urgh. I'm sorry about that. What can we do to help? Is the issue just
that I am not marking commits or something else?

Alistair
Re: [PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Akihiko Odaki 2 weeks, 1 day ago
Hi,

First, thank you for your work maintaining the stable series.

On 2026/07/11 16:47, Michael Tokarev wrote:
> On 7/1/26 12:22, Daniel Henrique Barboza 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 <daniel.barboza@oss.qualcomm.com>
>> ---
>>   hw/riscv/riscv-iommu.c | 29 +++++++++++++++++++++++------
>>   1 file changed, 23 insertions(+), 6 deletions(-)
> 
> For the stable qemu series (currently 10.0.x-LTS and 11.0.x), in order
> to pick this commit, I also picked v11.0.0-1212-gca7bac51e04
> "hw/riscv/riscv-iommu: Avoid caching PCI device IDs" by Chengbo Gao
> (Cc'ed) - because it touched the same code and there's a merge conflict.
> I can edit this patch ("set ftype and iova in riscv_iommu_ctx()") instead,
> but it felt that ca7bac51e04 is also a good pick for the stable series.
> 
> Additionally for 10.0.x-LTS series, I also picked 2 more commits:
> 
> v10.2.0-323-g15406cc593a "hw/riscv: riscv-iommu: Don't look up DDT cache
>   in Off and Bare modes" by Frank Chang (Cc'ed), which avoids a merge
>   conflict and also looks like a (maybe missing) bugfix.
> 
> v10.2.0-312-gc497ef6739c "hw/riscv/riscv-iommu: Fix MemoryRegion owner"
>   by Akihiko Odaki, which I spotted when looking for the history of
>   changes, and which looked like an obvious bugfix.

This particular change is somewhat orthogonal to the broader issue you 
describe with RISC-V patches. I found it through a codebase-wide search 
for incorrect MemoryRegion ownership, rather than while following the 
evolution of the RISC-V code. The same search found a similar issue 
elsewhere, which you have already picked up:

https://lore.kernel.org/qemu-devel/20251121184424.1137669-18-mjt@tls.msk.ru/
("[Stable-10.0.7 18/81] hw/nvram/ds1225y: Fix nvram MemoryRegion owner")

Unfortunately, there are several recurring patterns of MemoryRegion 
misuse, and in some cases I am not entirely sure what the correct 
ownership should be. In any case, this is separate from the concerns 
around fast-moving RISC-V development.

This particular change is trivial; it corrects semantically incorrect 
code, but I am not sure whether the bug has any user-visible effect.

Regards,
Akihiko Odaki

> 
> Hopefully this is okay.  Unfortunately even the simpler changes brings
> up quite a lot of missing fixes just by a chance - this means that we
> either not doing a good job keeping stable series up to date (by marking
> commits fixing stuff for-stable), or we should not try fixing stuff in
> previous series for a too-fast-moving target.
> 
> I'm sorry I'm bringing up this more general question in a very narrow
> context of this particular fix (which might not even be important
> enough).  Maybe I should discuss this separately.  Overall, I'm
> having some.. issues with riscv pullreqs in context of stable series,
> it's always more time-consuming to handle these and a bit more difficult
> to decide what is imortant and what can be skipped.
> 
> Thanks,
> 
> /mjt
> 


Re: [PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Philippe Mathieu-Daudé 2 weeks, 5 days ago
On 1/7/26 11:22, Daniel Henrique Barboza 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 <daniel.barboza@oss.qualcomm.com>
> ---
>   hw/riscv/riscv-iommu.c | 29 +++++++++++++++++++++++------
>   1 file changed, 23 insertions(+), 6 deletions(-)


> @@ -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;

s/uint32_t/enum riscv_iommu_fq_ttypes/ (can be cleaned later).
Re: [PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Philippe Mathieu-Daudé 2 weeks, 5 days ago
On 7/7/26 08:35, Philippe Mathieu-Daudé wrote:
> On 1/7/26 11:22, Daniel Henrique Barboza 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 <daniel.barboza@oss.qualcomm.com>
>> ---
>>   hw/riscv/riscv-iommu.c | 29 +++++++++++++++++++++++------
>>   1 file changed, 23 insertions(+), 6 deletions(-)
> 
> 
>> @@ -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;
> 
> s/uint32_t/enum riscv_iommu_fq_ttypes/ (can be cleaned later).

(and if cleaning that, also riscv_iommu_report_fault() argument)

Re: [PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Alistair Francis 2 weeks, 5 days ago
On Wed, Jul 1, 2026 at 7:23 PM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> 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 <daniel.barboza@oss.qualcomm.com>

Thanks!

Applied to riscv-to-apply.next

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
>
>
Re: [PATCH] hw/riscv/riscv-iommu.c: set ftype and iova in riscv_iommu_ctx()
Posted by Alistair Francis 2 weeks, 6 days ago
On Wed, Jul 1, 2026 at 7:23 PM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> 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 <daniel.barboza@oss.qualcomm.com>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

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
>
>