hw/riscv/riscv-iommu.c: fault for non-user PTE in G_STAGE
riscv-iommu spec 1.0 says: "When checking the U bit in a second-stage PTE, the transaction is treated as not requesting supervisor privilege." We need to *always* fault in case we're on G_STAGE and PTE_U is cleared since we can't be on supervisor mode at this point. Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3555 Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Message-ID: <20260701121111.537654-4-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Daniel Henrique Barboza committed
Jul 1, 2026 at 09:11 UTC
9158c900ab308cbb8a70edcc7358efab7b34730e
1 file changed
+10
hw/riscv/riscv-iommu.c
+10
@@ -495,6 +495,16 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
495
break; /* Access bit not set */
496
} else if ((iotlb->perm & IOMMU_WO) && !ade && !(pte & PTE_D)) {
497
break; /* Dirty bit not set */
498
+ } else if (pass == G_STAGE && !(pte & PTE_U)) {
499
+ /*
500
+ * riscv-iommu spec 1.0: "When checking the U bit in a
501
+ * second-stage PTE, the transaction is treated as
502
+ * not requesting supervisor privilege."
503
+ *
504
+ * I.e. we need to fault if this is a non-user PTE since
505
+ * we are always in user mode at this point.
506
+ */
507
+ break;
508
} else {
509
/* Leaf PTE, translation completed. */
510
sc[pass].step = sc[pass].levels;