Hi,
On 9/1/25 2:00 PM, Akihiko Odaki wrote:
> Remove the lower bound of the Highmem IO Regions' addresses for the
> latest machine version to increase the chance to fit the regions in the
> PA space.
>
> The lower bound was especially problematic when using virt-install on
> Apple M2. virt-install 5.0.0 adds multiple pcie-root-port devices that
> require sufficient space in the ECAM region. However, the Highmem ECAM
> region did not fit in the limited PA space on the hardware, and the ECAM
> region size was limited to 16 MiB. If virt-install had added more than
> 16 devices to the root bridge, the region overflowed, which prevented
> edk2-stable202505 from scanning PCI devices, including the boot disk,
> causing boot failures.
>
> Ideally, a virtual machine with more than 16 devices added to the root
> bridge should just work so that users and management layers do not have
> to care whether they use constrained hardware.
>
> The base address of the Highmem IO Regions was fixed when commit
> f90747c4e8fb ("hw/arm/virt: GICv3 DT node with one or two redistributor
> regions") added the first Highmem IO Region. Later, commit 957e32cffa57
> ("hw/arm/virt: Dynamic memory map depending on RAM requirements")
> allowed moving the Highmem IO Regions to higher addresses to accommodate
> RAM more than 255 GiB, but the lower bound remained to keep the legacy
> memory map.
>
> Remove the lower bound for the latest machine version to accommodate more
> devices with the root bridge. Keeping the lower bound for the old
> machine versions ensures the compatibility is still maintained.
>
> Signed-off-by: Akihiko Odaki <[email protected]>
This looks good to me.
Reviewed-by: Eric Auger <[email protected]>Eric > --- > Changes in v2: > - Rebased. > - Link to v1: > https://lore.kernel.org/qemu-devel/[email protected] > --- > include/hw/arm/virt.h | 1 + > hw/arm/virt.c | 16 ++++++++++++---- > 2 files changed, 13 insertions(+), 4 deletions(-) > > diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h > index > 365a28b082cae36321ed906d9a13242997fa543a..341eb171d084b911e05b9861b9f4ba516fa2888e > 100644 > --- a/include/hw/arm/virt.h > +++ b/include/hw/arm/virt.h > @@ -120,6 +120,7 @@ typedef enum VirtGICType { > > struct VirtMachineClass { > MachineClass parent; > + hwaddr min_highmem_base; > bool no_tcg_its; > bool no_highmem_compact; > bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */ > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > index > 1e63f40fbece3997dedc8aa953957471f930d44c..3cb978dae2ec0cdd9e7b902b3b427dac8a27bebf > 100644 > --- a/hw/arm/virt.c > +++ b/hw/arm/virt.c > @@ -1887,6 +1887,7 @@ static void virt_set_high_memmap(VirtMachineState *vms, > static void virt_set_memmap(VirtMachineState *vms, int pa_bits) > { > MachineState *ms = MACHINE(vms); > + VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); > hwaddr base, device_memory_base, device_memory_size, memtop; > int i; > > @@ -1913,8 +1914,7 @@ static void virt_set_memmap(VirtMachineState *vms, int > pa_bits) > /* > * We compute the base of the high IO region depending on the > * amount of initial and device memory. The device memory start/size > - * is aligned on 1GiB. We never put the high IO region below 256GiB > - * so that if maxram_size is < 255GiB we keep the legacy memory map. > + * is aligned on 1GiB. > * The device region size assumes 1GiB page max alignment per slot. > */ > device_memory_base = > @@ -1932,8 +1932,8 @@ static void virt_set_memmap(VirtMachineState *vms, int > pa_bits) > error_report("maxmem/slots too huge"); > exit(EXIT_FAILURE); > } > - if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) { > - base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES; > + if (base < vmc->min_highmem_base) { > + base = vmc->min_highmem_base; > } > > /* We know for sure that at least the memory fits in the PA space */ > @@ -3464,8 +3464,16 @@ DEFINE_VIRT_MACHINE_AS_LATEST(10, 2) > > static void virt_machine_10_1_options(MachineClass *mc) > { > + VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); > + > virt_machine_10_2_options(mc); > compat_props_add(mc->compat_props, hw_compat_10_1, hw_compat_10_1_len); > + > + /* > + * Do not put the high IO region below 256GiB so that if maxram_size is > + * < 255GiB we keep the legacy memory map. > + */ > + vmc->min_highmem_base = base_memmap[VIRT_MEM].base + > LEGACY_RAMLIMIT_BYTES; > } > DEFINE_VIRT_MACHINE(10, 1) > > > --- > base-commit: e101d33792530093fa0b0a6e5f43e4d8cfe4581e > change-id: 20250728-virt-833dafa6c11b > > Best regards,
