Commit ce7fb32827 for qemu.org
commit ce7fb3282756c04433274e3abcd59407f77c4923
Author: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Date: Wed Jul 1 06:22:41 2026 -0300
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>
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index 877d24bc47..f6865d1e16 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -1430,6 +1430,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;
@@ -1439,6 +1440,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);
@@ -1481,8 +1483,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;
@@ -2233,6 +2248,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;
@@ -2240,7 +2257,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 |
@@ -2248,7 +2265,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,
};
@@ -2587,7 +2604,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 {
@@ -2889,7 +2906,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;