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;