[PATCH v6 6/7] hw/riscv: Set IOMMU PAS via property

Anton Johansson via qemu development posted 7 patches 1 month ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Helge Deller <deller@gmx.de>, Song Gao <gaosong@loongson.cn>, Bibo Mao <maobibo@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Paolo Bonzini <pbonzini@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Peter Maydell <peter.maydell@linaro.org>, Michael Rolnik <mrolnik@gmail.com>, Brian Cain <brian.cain@oss.qualcomm.com>, Zhao Liu <zhao1.liu@intel.com>, Marcelo Tosatti <mtosatti@redhat.com>, Eduardo Habkost <eduardo@habkost.net>, Laurent Vivier <laurent@vivier.eu>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Aurelien Jarno <aurelien@aurel32.net>, Aleksandar Rikalo <arikalo@gmail.com>, Stafford Horne <shorne@gmail.com>, Nicholas Piggin <npiggin@gmail.com>, Chinmay Rath <rathc@linux.ibm.com>, Yoshinori Sato <yoshinori.sato@nifty.com>, Ilya Leoshkevich <iii@linux.ibm.com>, David Hildenbrand <david@kernel.org>, Thomas Huth <thuth@redhat.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>, Bastian Koppelmann <kbastian@rumtueddeln.de>, Max Filippov <jcmvbkbc@gmail.com>
[PATCH v6 6/7] hw/riscv: Set IOMMU PAS via property
Posted by Anton Johansson via qemu development 1 month ago
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>
---
 hw/riscv/riscv-iommu.h     | 1 +
 hw/riscv/riscv-iommu-pci.c | 3 +++
 hw/riscv/riscv-iommu.c     | 8 ++++----
 hw/riscv/virt.c            | 7 +++++++
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h
index 2dabd86941..2a9f6fccd5 100644
--- a/hw/riscv/riscv-iommu.h
+++ b/hw/riscv/riscv-iommu.h
@@ -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 */
diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
index 5f7d359204..14dd5f3857 100644
--- a/hw/riscv/riscv-iommu-pci.c
+++ b/hw/riscv/riscv-iommu-pci.c
@@ -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[] = {
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index b46b337375..98345b1280 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -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),
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 07e66b3936..bbce2fb667 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -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);
     }

-- 
2.52.0
Re: [PATCH v6 6/7] hw/riscv: Set IOMMU PAS via property
Posted by Chao Liu 1 month ago
On Wed, Feb 18, 2026 at 06:21:32PM +0100, Anton Johansson wrote:
> 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>
> ---
>  hw/riscv/riscv-iommu.h     | 1 +
>  hw/riscv/riscv-iommu-pci.c | 3 +++
>  hw/riscv/riscv-iommu.c     | 8 ++++----
>  hw/riscv/virt.c            | 7 +++++++
>  4 files changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h
> index 2dabd86941..2a9f6fccd5 100644
> --- a/hw/riscv/riscv-iommu.h
> +++ b/hw/riscv/riscv-iommu.h
> @@ -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 */
> diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
> index 5f7d359204..14dd5f3857 100644
> --- a/hw/riscv/riscv-iommu-pci.c
> +++ b/hw/riscv/riscv-iommu-pci.c
> @@ -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[] = {
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index b46b337375..98345b1280 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -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),
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 07e66b3936..bbce2fb667 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -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);
>      }
> 
> -- 
> 2.52.0
> 
LGTM :)

Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>

Thanks,
Chao