@samitouri / QOSamiQemu / commits / 3a3cfcb29f

hw/riscv: Set IOMMU PAS via property

Replaces the only remaining use of TARGET_PHYS_ADDR_SPACE_BITS for RISCV with a property RISCVIOMMUState::pas_bits that gets written to the capabilities field upon device realization. This write needs to happen at realize-time to ensure the property has been set. For the virt machine and sysbus device, pas_bits is set by virt_machine_init() to either 34 or 56 bits, retaining previous behaviour. However, for the PCI device we do not have access to the CPU state, and instead use the maximum riscv64 value of 56 bits. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Anton Johansson <anjo@rev.ng> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com> Message-ID: <20260218-phys_addr-v6-6-a603bf363218@rev.ng> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Anton Johansson committed Feb 16, 2026 at 17:28 UTC 3a3cfcb29fd2f71195c8cbf6d6311e37f3810315
4 files changed +15 -4
hw/riscv/riscv-iommu-pci.c
+3
@@ -158,6 +158,9 @@ static void riscv_iommu_pci_init(Object *obj)
158
159 iommu->icvec_avail_vectors = RISCV_IOMMU_PCI_ICVEC_VECTORS;
160 riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_MSI);
161 +
162 + /* Report maximum physical address size of riscv64 */
163 + iommu->pas_bits = 56;
164 }
165
166 static const Property riscv_iommu_pci_properties[] = {
hw/riscv/riscv-iommu.c
+4 -4
@@ -2453,10 +2453,6 @@ static void riscv_iommu_instance_init(Object *obj)
2453 /* Enable translation debug interface */
2454 s->cap = RISCV_IOMMU_CAP_DBG;
2455
2456 - /* Report QEMU target physical address space limits */
2457 - s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS,
2458 - TARGET_PHYS_ADDR_SPACE_BITS);
2459 -
2456 /* TODO: method to report supported PID bits */
2457 s->pid_bits = 8; /* restricted to size of MemTxAttrs.pid */
2458 s->cap |= RISCV_IOMMU_CAP_PD8;
@@ -2487,6 +2483,9 @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp)
2483 {
2484 RISCVIOMMUState *s = RISCV_IOMMU(dev);
2485
2486 + /* Report QEMU target physical address space limits. */
2487 + s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS, s->pas_bits);
2488 +
2489 s->cap |= s->version & RISCV_IOMMU_CAP_VERSION;
2490 if (s->enable_msi) {
2491 s->cap |= RISCV_IOMMU_CAP_MSI_FLAT | RISCV_IOMMU_CAP_MSI_MRIF;
@@ -2645,6 +2644,7 @@ void riscv_iommu_reset(RISCVIOMMUState *s)
2644 static const Property riscv_iommu_properties[] = {
2645 DEFINE_PROP_UINT32("version", RISCVIOMMUState, version,
2646 RISCV_IOMMU_SPEC_DOT_VER),
2647 + DEFINE_PROP_UINT32("pas-bits", RISCVIOMMUState, pas_bits, 0),
2648 DEFINE_PROP_UINT32("bus", RISCVIOMMUState, bus, 0x0),
2649 DEFINE_PROP_UINT32("ioatc-limit", RISCVIOMMUState, iot_limit,
2650 LIMIT_CACHE_IOT),
hw/riscv/riscv-iommu.h
+1
@@ -34,6 +34,7 @@ struct RISCVIOMMUState {
34 /*< public >*/
35 uint32_t version; /* Reported interface version number */
36 uint32_t pid_bits; /* process identifier width */
37 + uint32_t pas_bits; /* physical address bits */
38 uint32_t bus; /* PCI bus mapping for non-root endpoints */
39
40 uint64_t cap; /* IOMMU supported capabilities */
hw/riscv/virt.c
+7
@@ -1739,6 +1739,13 @@ static void virt_machine_init(MachineState *machine)
1739 object_property_set_link(OBJECT(iommu_sys), "irqchip",
1740 OBJECT(mmio_irqchip),
1741 &error_fatal);
1742 + /*
1743 + * For riscv64 use a physical address size of 56 bits (44 bit PPN),
1744 + * and for riscv32 use 34 bits (22 bit PPN).
1745 + */
1746 + object_property_set_uint(OBJECT(iommu_sys), "pas-bits",
1747 + riscv_is_32bit(&s->soc[0]) ? 34 : 56,
1748 + &error_fatal);
1749
1750 sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
1751 }