@samitouri / QOSamiQemu / commits / ce7fb32827

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

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> Message-ID: <20260701092241.307801-1-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Daniel Henrique Barboza committed Jul 1, 2026 at 06:22 UTC ce7fb3282756c04433274e3abcd59407f77c4923
1 file changed +23 -6
hw/riscv/riscv-iommu.c
+23 -6
@@ -1430,6 +1430,7 @@ static void riscv_iommu_ctx_inval(RISCVIOMMUState *s, GHFunc func,
1430 /* Find or allocate translation context for a given {device_id, process_id} */
1431 static RISCVIOMMUContext *riscv_iommu_ctx(RISCVIOMMUState *s,
1432 unsigned devid, unsigned process_id,
1433 + IOMMUAccessFlags perm, uint64_t iova,
1434 void **ref)
1435 {
1436 GHashTable *ctx_cache;
@@ -1439,6 +1440,7 @@ static RISCVIOMMUContext *riscv_iommu_ctx(RISCVIOMMUState *s,
1440 .process_id = process_id,
1441 };
1442 unsigned mode = get_field(s->ddtp, RISCV_IOMMU_DDTP_MODE);
1443 + uint32_t fault_type;
1444
1445 ctx_cache = g_hash_table_ref(s->ctx_cache);
1446
@@ -1481,8 +1483,21 @@ static RISCVIOMMUContext *riscv_iommu_ctx(RISCVIOMMUState *s,
1483 g_hash_table_unref(ctx_cache);
1484 *ref = NULL;
1485
1484 - riscv_iommu_report_fault(s, ctx, RISCV_IOMMU_FQ_TTYPE_UADDR_RD,
1485 - fault, !!process_id, 0, 0);
1486 + /*
1487 + * TODO: (1) do we need to distinguish other fault types
1488 + * for ctx fetching and (2) evaluate putting the 'fault_type'
1489 + * logic inside riscv_iommu_report_fault() - there's at
1490 + * least one other place (end of riscv_iommu_translate())
1491 + * that does something similar.
1492 + */
1493 + if (perm & IOMMU_RO) {
1494 + fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_RD;
1495 + } else {
1496 + fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_WR;
1497 + }
1498 +
1499 + riscv_iommu_report_fault(s, ctx, fault_type, fault,
1500 + !!process_id, iova, 0);
1501
1502 g_free(ctx);
1503 return NULL;
@@ -2233,6 +2248,8 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
2248 uint64_t ctrl = riscv_iommu_reg_get64(s, RISCV_IOMMU_REG_TR_REQ_CTL);
2249 unsigned devid = get_field(ctrl, RISCV_IOMMU_TR_REQ_CTL_DID);
2250 unsigned pid = get_field(ctrl, RISCV_IOMMU_TR_REQ_CTL_PID);
2251 + IOMMUAccessFlags perm = ctrl & RISCV_IOMMU_TR_REQ_CTL_NW
2252 + ? IOMMU_RO : IOMMU_RW;
2253 RISCVIOMMUContext *ctx;
2254 void *ref;
2255
@@ -2240,7 +2257,7 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
2257 return;
2258 }
2259
2243 - ctx = riscv_iommu_ctx(s, devid, pid, &ref);
2260 + ctx = riscv_iommu_ctx(s, devid, pid, perm, iova, &ref);
2261 if (ctx == NULL) {
2262 riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_TR_RESPONSE,
2263 RISCV_IOMMU_TR_RESPONSE_FAULT |
@@ -2248,7 +2265,7 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
2265 } else {
2266 IOMMUTLBEntry iotlb = {
2267 .iova = iova,
2251 - .perm = ctrl & RISCV_IOMMU_TR_REQ_CTL_NW ? IOMMU_RO : IOMMU_RW,
2268 + .perm = perm,
2269 .addr_mask = ~0,
2270 .target_as = NULL,
2271 };
@@ -2587,7 +2604,7 @@ static MemTxResult riscv_iommu_trap_write(void *opaque, hwaddr addr,
2604 /* FIXME: PCIe bus remapping for attached endpoints. */
2605 devid |= s->bus << 8;
2606
2590 - ctx = riscv_iommu_ctx(s, devid, 0, &ref);
2607 + ctx = riscv_iommu_ctx(s, devid, 0, IOMMU_RW, addr, &ref);
2608 if (ctx == NULL) {
2609 res = MEMTX_ACCESS_ERROR;
2610 } else {
@@ -2889,7 +2906,7 @@ static IOMMUTLBEntry riscv_iommu_memory_region_translate(
2906 };
2907 uint32_t devid = riscv_iommu_space_devid(as);
2908
2892 - ctx = riscv_iommu_ctx(as->iommu, devid, iommu_idx, &ref);
2909 + ctx = riscv_iommu_ctx(as->iommu, devid, iommu_idx, flag, addr, &ref);
2910 if (ctx == NULL) {
2911 /* Translation disabled or invalid. */
2912 iotlb.addr_mask = 0;