RE: [PATCH v2] PCI: hv: Allocate MMIO from above 4GB for the config window
From: Dexuan Cui
Date: Wed Apr 15 2026 - 12:50:56 EST
> From: Dexuan Cui <DECUI@xxxxxxxxxxxxx>
> Sent: Wednesday, April 15, 2026 8:31 AM
> ...
> 4) For Gen1 VMs, the framebuffer always starts at the fixed
> location 4G-128MB.
>
> 4.1) By default, the low mmio range also starts at 4G-128MB,
> and the size is 127.75 MB, i.e. if
> hdev->channel->offermsg.offer.mmio_megabytes needs 128MB,
> the guest hyperv_drm driver can't find enough available
> mmio in the low mmio range, and has to use the high mmio
> range.
>
> 4.2) With "Set-VM -LowMemoryMappedIoSpace 1GB", the
> low_mmio_base is 3GB, the low_mmio_size=1023.75 MB. The
> fb_mmio_base is still 4G-128MB, i.e. if hyperv_drm needs
> 128 MB of mmio, it still has to use the high mmio range.
Well, this is inaccurate: in this case we could reserve 128MB low
mmio for hyperv_drm, but this is not really what we want: our
purpose is that we reserve the "initial" framebuffer mmio range so that
hyperv_drm in the first kernel doesn't have to relocate the framebuffer
mmio range. Even if we reserve 128MB low mmio for hyperv_drm
starting at 1GB:
a) hyperv_drm can be blacklisted by the users so from the host perspective,
it's still the "initial" framebuffer mmio range that takes affect, and we still
can have the mmio conflict in the kdump kernel.
b) hyperv_drm can load after hv_pci, so we can even have the mmio
conflict in the first kernel.
> On an ARM64 lab host, I also tested Gen2 VMs (there is no Gen1 VM
> for ARM VMs):
>
> By default:
> low_mmio_base = 4GB - 512MB, i.e. 0xe0000000
> low_mmio_size = 512MB
> fb_mmio_base = low_mmio_base
> The default framebuffer size is 3MB
> (i.e. screen.lfb_size = 3MB) but hyperv_drm:
> mmio_megabytes = 8 MB, which supports up to 1920 * 1080.
>
> With the below commands:
> Set-VM -LowMemoryMappedIoSpace 512MB \
> -VMName decui-u2204-gen2-fb
> // the command only accepts a value between 512MB and 3.5GB.
> Set-VMVideo -VMName decui-u2204-gen2-fb \
> -HorizontalResolution 4834 \
> -VerticalResolution 3622 \
> -ResolutionType Single
> I thought we would have:
> max_fb_size = round_up_to_2MB(4834*3622*4) = 68 MB
> excess_fb_size = 4MB
> low_mmio_base = 4GB - 512MB - 4MB * 2
> = 4GB - 520MB
> fb_mmio_base = low_mmio_base
> low_mmio_size = 4GB - low_mmio_base = 520MB
>
> Since 4GB - target_low_mmio_size = 4GB - 512MB, which is
> smaller than low_mmio_base, so low_mmio_base and
Sorry for the typo: here the "smaller" should be "bigger".
> fb_mmio_base would be both set to 4GB - 520MB, and
> low_mmio_size would be 520MB.
>
> However, the actual result is:
> max_fb_size is indeed 68MB.
> but fb_mmio_base = low_mmio_base = 4GB - 512MB, and
> low_mmio_size = 512MB, i.e. the 'excess_fb_size' is not
> considered on ARM64!
I think this makes senses since " low_mmio_size = 512MB" is
already bigger enough for the framebuffer.
> In this case, we'd like to reserve
> min(low_mmio_size/2, 128MB) = 128MB for the framebuffer
> mmio, since the max possible framebuffer so far is 128MB.
>
Thanks,
Dexuan