> -----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