On 7/1/2026 4:31 AM, Daniel Henrique Barboza wrote:
We must check if IOHGATP_PPN is 16kb aligned for non-bare GATP modes.
qos-riscv-iommu.h needs change too since G_IOHGATP must now be 16kb
aligned too.
Fixes: 69a9ae4836 ("hw/riscv/riscv-iommu: add ATS support")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3550
Signed-off-by: Daniel Henrique Barboza <[email protected]>
---
hw/riscv/riscv-iommu.c | 14 ++++++++++++++
tests/qtest/libqos/qos-riscv-iommu.h | 2 +-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index 891a56e731..09990c640f 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -795,6 +795,20 @@ static bool
riscv_iommu_validate_device_ctx(RISCVIOMMUState *s,
return false;
}
+ if (gatp != RISCV_IOMMU_DC_IOHGATP_MODE_BARE) {
+ uint64_t iohgatp_ppn = get_field(ctx->gatp,
+ RISCV_IOMMU_DC_IOHGATP_PPN);
Seems it should be like the following:
+ uint64_t iohgatp_ppn = PPN_PHYS(get_field(ctx->gatp,
+ RISCV_IOMMU_DC_IOHGATP_PPN));
Otherwise,
Reviewed-by: Nutty Liu <[email protected]>
Thanks,
Nutty
+ /*
+ * One of the conditions for a misconfigured DDT entry
+ * according to the riscv-spec: "DC.iohgatp.MODE is not
+ * Bare and the root page table determined by DC.iohgatp.PPN
+ * is not aligned to a 16-KiB boundary."
+ */
+ if (iohgatp_ppn & ((1ULL << 14) - 1)) {
+ return false;
+ }
+ }
+
fsc_mode = get_field(ctx->satp, RISCV_IOMMU_DC_FSC_MODE);
if (ctx->tc & RISCV_IOMMU_DC_TC_PDTV) {
diff --git a/tests/qtest/libqos/qos-riscv-iommu.h
b/tests/qtest/libqos/qos-riscv-iommu.h
index 90e69a5d73..4a972401f5 100644
--- a/tests/qtest/libqos/qos-riscv-iommu.h
+++ b/tests/qtest/libqos/qos-riscv-iommu.h
@@ -46,7 +46,7 @@
#define QRIOMMU_L1_PTE_VAL 0x0000000000012000ull
#define QRIOMMU_L2_PTE_VAL 0x0000000000013000ull
-#define QRIOMMU_G_IOHGATP 0x0000000000020000ull
+#define QRIOMMU_G_IOHGATP 0x0000000008000000ull
#define QRIOMMU_G_L0_PTE_VAL 0x0000000000021000ull
#define QRIOMMU_G_L1_PTE_VAL 0x0000000000022000ull