> -----Original Message-----
> From: Tushar Dave <[email protected]>
> Sent: 16 September 2026 19:56
> To: [email protected]
> Cc: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; Alex Williamson
> <[email protected]>; Jason Gunthorpe <[email protected]>; Shameer
> Kolothum Thodi <[email protected]>
> Subject: [PATCH 5/5] hw/arm/virt: add highmem-mmio-base property
> 
> Add a highmem-mmio-base property to override the base of the virt
> machine's high PCIe MMIO window, alongside the existing
> highmem-mmio-size:
> 
>   -machine virt,highmem-mmio-base=<addr>,highmem-mmio-size=<size>
> 
> Some PCI devices require MMIO resources to be placed within a
> specific address range that cannot be satisfied by the default
> placement. The configured base is validated to be non-zero, aligned
> to highmem-mmio-size, non-overlapping with the existing high memory
> layout, and within the configured physical address space.
> 
> Signed-off-by: Tushar Dave <[email protected]>
> ---
>  hw/arm/virt.c | 62
> ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 61 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index c5db663858..3a554dd26c 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2513,9 +2513,34 @@ static void
> virt_set_high_memmap(VirtMachineState *vms,
> 
>      for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap);
> i++) {
>          region_enabled = virt_get_high_memmap_enabled(vms, i);
> -        region_base = ROUND_UP(base, extended_memmap[i].size);
>          region_size = extended_memmap[i].size;
> 
> +        if (i == VIRT_HIGH_PCIE_MMIO && extended_memmap[i].base) {
> +            region_base = extended_memmap[i].base;
> +
> +            if (region_base < base) {
> +                error_report("highmem-mmio-base 0x%"PRIx64" overlaps prior "
> +                             "high memory layout (must be >= 0x%"PRIx64")",
> +                             region_base, base);
> +                exit(1);
> +            }
> +            if (region_base % region_size != 0) {
> +                error_report("highmem-mmio-base 0x%"PRIx64" must be "
> +                             "aligned to highmem-mmio-size 0x%"PRIx64,
> +                             region_base, region_size);
> +                exit(1);
> +            }
> +            if (region_base + region_size > BIT_ULL(pa_bits)) {

region_base + region_size can overflow and bypass this check.

> +                error_report("highmem-mmio-base + highmem-mmio-size "
> +                             "[0x%"PRIx64", 0x%"PRIx64") exceeds %d-bit PA "
> +                             "space", region_base,
> +                             region_base + region_size, pa_bits);
> +                exit(1);
> +            }
> +        } else {
> +            region_base = ROUND_UP(base, region_size);
> +        }
> +
>          vms->memmap[i].base = region_base;
>          vms->memmap[i].size = region_size;
> 
> @@ -3416,6 +3441,33 @@ static void virt_set_highmem_mmio_size(Object
> *obj, Visitor *v,
>      extended_memmap[VIRT_HIGH_PCIE_MMIO].size = size;
>  }
> 
> +static void virt_get_highmem_mmio_base(Object *obj, Visitor *v,
> +                                       const char *name, void *opaque,
> +                                       Error **errp)
> +{
> +    uint64_t base = extended_memmap[VIRT_HIGH_PCIE_MMIO].base;
> +
> +    visit_type_size(v, name, &base, errp);
> +}
> +
> +static void virt_set_highmem_mmio_base(Object *obj, Visitor *v,
> +                                       const char *name, void *opaque,
> +                                       Error **errp)
> +{
> +    uint64_t base;
> +
> +    if (!visit_type_size(v, name, &base, errp)) {
> +        return;
> +    }
> +
> +    if (base == 0) {
> +        error_setg(errp, "highmem-mmio-base cannot be 0");
> +        return;
> +    }
> +
> +    extended_memmap[VIRT_HIGH_PCIE_MMIO].base = base;
> +}
> +
>  static char *virt_get_msi(Object *obj, Error **errp)
>  {
>      VirtMachineState *vms = VIRT_MACHINE(obj);
> @@ -4286,6 +4338,14 @@ static void virt_machine_class_init(ObjectClass
> *oc, const void *data)
>                                            "Set the high memory region size "
>                                            "for PCI MMIO");
> 
> +    object_class_property_add(oc, "highmem-mmio-base", "size",
> +                                   virt_get_highmem_mmio_base,
> +                                   virt_set_highmem_mmio_base,
> +                                   NULL, NULL);
> +    object_class_property_set_description(oc, "highmem-mmio-base",
> +                                          "Set the high memory region base "
> +                                          "for PCI MMIO");
> +

Add this to docs/system/arm/virt.rst as well.

Thanks,
Shameer

Reply via email to