]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
hw/riscv: Set IOMMU PAS via property
authorAnton Johansson <anjo@rev.ng>
Mon, 16 Feb 2026 16:28:43 +0000 (17:28 +0100)
committerPhilippe Mathieu-Daudé <philmd@linaro.org>
Wed, 25 Feb 2026 22:46:04 +0000 (23:46 +0100)
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>
hw/riscv/riscv-iommu-pci.c
hw/riscv/riscv-iommu.c
hw/riscv/riscv-iommu.h
hw/riscv/virt.c

index 5f7d3592047a8f2b1db51e7bba20cf0292e24fb3..14dd5f3857e10d2b34fd0f0cdf78dff6d324061b 100644 (file)
@@ -158,6 +158,9 @@ static void riscv_iommu_pci_init(Object *obj)
 
     iommu->icvec_avail_vectors = RISCV_IOMMU_PCI_ICVEC_VECTORS;
     riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_MSI);
+
+    /* Report maximum physical address size of riscv64 */
+    iommu->pas_bits = 56;
 }
 
 static const Property riscv_iommu_pci_properties[] = {
index b46b337375aa3470f101be40386332fc68c3e765..98345b1280bd9e8f260059efc2b8e95a08f2a150 100644 (file)
@@ -2453,10 +2453,6 @@ static void riscv_iommu_instance_init(Object *obj)
     /* Enable translation debug interface */
     s->cap = RISCV_IOMMU_CAP_DBG;
 
-    /* Report QEMU target physical address space limits */
-    s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS,
-                       TARGET_PHYS_ADDR_SPACE_BITS);
-
     /* TODO: method to report supported PID bits */
     s->pid_bits = 8; /* restricted to size of MemTxAttrs.pid */
     s->cap |= RISCV_IOMMU_CAP_PD8;
@@ -2487,6 +2483,9 @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp)
 {
     RISCVIOMMUState *s = RISCV_IOMMU(dev);
 
+    /* Report QEMU target physical address space limits. */
+    s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS, s->pas_bits);
+
     s->cap |= s->version & RISCV_IOMMU_CAP_VERSION;
     if (s->enable_msi) {
         s->cap |= RISCV_IOMMU_CAP_MSI_FLAT | RISCV_IOMMU_CAP_MSI_MRIF;
@@ -2645,6 +2644,7 @@ void riscv_iommu_reset(RISCVIOMMUState *s)
 static const Property riscv_iommu_properties[] = {
     DEFINE_PROP_UINT32("version", RISCVIOMMUState, version,
         RISCV_IOMMU_SPEC_DOT_VER),
+    DEFINE_PROP_UINT32("pas-bits", RISCVIOMMUState, pas_bits, 0),
     DEFINE_PROP_UINT32("bus", RISCVIOMMUState, bus, 0x0),
     DEFINE_PROP_UINT32("ioatc-limit", RISCVIOMMUState, iot_limit,
         LIMIT_CACHE_IOT),
index 2dabd86941baf5b74d1fefe6833f19df157fd5f7..2a9f6fccd5216f799ff730ab5882f32ee450f745 100644 (file)
@@ -34,6 +34,7 @@ struct RISCVIOMMUState {
     /*< public >*/
     uint32_t version;     /* Reported interface version number */
     uint32_t pid_bits;    /* process identifier width */
+    uint32_t pas_bits;    /* physical address bits */
     uint32_t bus;         /* PCI bus mapping for non-root endpoints */
 
     uint64_t cap;         /* IOMMU supported capabilities */
index 07e66b39364ce2c35a752a2d8831fc4de5f8adf0..bbce2fb66716eec41e0f5f9645ef500a92fa6cbe 100644 (file)
@@ -1739,6 +1739,13 @@ static void virt_machine_init(MachineState *machine)
         object_property_set_link(OBJECT(iommu_sys), "irqchip",
                                  OBJECT(mmio_irqchip),
                                  &error_fatal);
+        /*
+         * For riscv64 use a physical address size of 56 bits (44 bit PPN),
+         * and for riscv32 use 34 bits (22 bit PPN).
+         */
+        object_property_set_uint(OBJECT(iommu_sys), "pas-bits",
+                                 riscv_is_32bit(&s->soc[0]) ? 34 : 56,
+                                 &error_fatal);
 
         sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
     }