@samitouri / QOSamiQemu / commits / 58e801f74e

hw/riscv/riscv-iommu-sys.c: record fault on IOMMU-generated MSI write

The riscv-iommu spec requires that the IOMMU records its own generated MSI write faults. Fixes: 01c1caa9d1 ("hw/riscv/virt.c, riscv-iommu-sys.c: add MSIx support") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3572 Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Nutty Liu <nutty.liu@hotmail.com> Message-ID: <20260629165954.1018123-1-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Daniel Henrique Barboza committed Jun 29, 2026 at 13:59 UTC 58e801f74e6a4ebd3a0cf3ab1a96e1676b263efd
3 files changed +17 -3
hw/riscv/riscv-iommu-sys.c
+15 -1
@@ -26,6 +26,7 @@
26 #include "qemu/host-utils.h"
27 #include "qemu/module.h"
28 #include "qom/object.h"
29 +#include "target/riscv/cpu_bits.h"
30 #include "trace.h"
31
32 #include "riscv-iommu.h"
@@ -143,7 +144,20 @@ static void riscv_iommu_sysdev_send_MSI(RISCVIOMMUStateSys *s,
144
145 address_space_stl_le(&address_space_memory, msi_addr,
146 msi_data, MEMTXATTRS_UNSPECIFIED, &result);
146 - trace_riscv_iommu_sys_msi_sent(vector, msi_addr, msi_data, result);
147 +
148 + if (result == MEMTX_OK) {
149 + trace_riscv_iommu_sys_msi_sent(vector, msi_addr, msi_data, result);
150 + } else {
151 + /* Record an access fault error in the fault queue */
152 + struct riscv_iommu_fq_record ev = { 0 };
153 + RISCVIOMMUState *iommu = &s->iommu;
154 +
155 + ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_CAUSE,
156 + RISCV_IOMMU_FQ_CAUSE_MSI_WR_FAULT);
157 + ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_TTYPE,
158 + RISCV_IOMMU_FQ_TTYPE_UADDR_WR);
159 + riscv_iommu_fault(iommu, &ev);
160 + }
161 }
162
163 static void riscv_iommu_sysdev_notify(RISCVIOMMUState *iommu,
hw/riscv/riscv-iommu.c
+1 -2
@@ -118,8 +118,7 @@ void riscv_iommu_notify(RISCVIOMMUState *s, int vec_type)
118 }
119 }
120
121 -static void riscv_iommu_fault(RISCVIOMMUState *s,
122 - struct riscv_iommu_fq_record *ev)
121 +void riscv_iommu_fault(RISCVIOMMUState *s, struct riscv_iommu_fq_record *ev)
122 {
123 uint32_t ctrl = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_FQCSR);
124 uint32_t head = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_FQH) & s->fq_mask;
hw/riscv/riscv-iommu.h
+1
@@ -103,6 +103,7 @@ void riscv_iommu_pci_setup_iommu(RISCVIOMMUState *iommu, PCIBus *bus,
103 void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode);
104 void riscv_iommu_reset(RISCVIOMMUState *s);
105 void riscv_iommu_notify(RISCVIOMMUState *s, int vec_type);
106 +void riscv_iommu_fault(RISCVIOMMUState *s, struct riscv_iommu_fq_record *ev);
107
108 typedef struct RISCVIOMMUContext RISCVIOMMUContext;
109 /* Device translation context state. */