From: Dexuan Cui <[email protected]> Sent: Wednesday, April 15, 2026 8:31 AM > > > From: Michael Kelley <[email protected]> Sent: Wednesday, April 8, 2026 > > 6:54 AM
[snip] > > Another example is: for a Gen2 VM with the below commands: > Set-VM -LowMemoryMappedIoSpace 1GB \ > -VMName decui-u2204-gen2-fb > // i.e. the default setting on Azure. Let's ignore CVMs here. FWIW, I'm seeing that in Gen2 VMs in Azure, the low_mmio_size is 3 GiB. I'm looking at a D16ds_v5, and a D16lds_v6. The v5 VM is newly created, while the v6 has been around for a few months. In a CVM, the low_mmio_size should be 1 GiB. This overall example is still correct -- it's just the comment that I have doubts about. Or maybe you are looking at a different VM size that has a different default? Some years back, I had gotten into a discussion with Azure about this size because the swiotlb memory wants to be allocated below the 4 GiB line, and reserving 3 GiB for low mmio limited the size of the swiotlb. CVMs were changed to have only 1 GiB for low mmio because they need a larger swiotlb. > Set-VMVideo -VMName decui-u2204-gen2-fb \ > -HorizontalResolution 4834 \ > -VerticalResolution 3622 \ > -ResolutionType Single > we have: > max_fb_size = round_up_to_2MB(4834*3622*4) = 68 MB > excess_fb_size = 4MB > low_mmio_base = 4GB - 128MB - 4MB * 2 > = 4GB - 136 MB = 0xf7800000 > but 4GB - target_low_mmio_size = 4GB - 1GB, which is > smaller than low_mmio_base, so low_mmio_base and > fb_mmio_base are both set to 4GB - 1GB = 0xc0000000, > and low_mmio_size = 1GB. > 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. > > ************************************ > > 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 > 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! > > 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. > > With the below command: > Set-VM -LowMemoryMappedIoSpace 3GB \ > -VMName decui-u2204-gen2-fb > // i.e. the default setting on Azure. Unlike x86-64, an ARM64 > // VM on Azure has 3GB of mmio below 4GB. See my previous comment on the same topic. I think arm64 and x86/x64 are the same. > Set-VMVideo -VMName decui-u2204-gen2-fb \ > -HorizontalResolution 4834 \ > -VerticalResolution 3622 \ > -ResolutionType Single > we have: > max_fb_size = round_up_to_2MB(4834*3622*4) = 68 MB > low_mmio_base = 4GB - 3GB = 1GB = 0x40000000 > low_mmio_size = 3GB > fb_mmio_base = low_mmio_base = 1GB > > 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. > > ************************************ > > To recap, I think the bottom line is: > > a) For Gen2 VMs, we can safely reserve a mmio range starting at > sysfb_primary_display.screen.lfb_base with a size of > min(low_mmio_size/2, 128MB). > > If sysfb_primary_display.screen.lfb_base is 0, i.e. in the case > of kdump kernel, we use low_mmio_base instead. > This should fix the mmio conflict in the kdump kernel. > > b) For Gen1 VMs, let's still only reserve a mmio range starting at > 4GB - 128MB with a size of 64MB, because when we are in > vmbus_reserve_fb(), we still don't know the exact size of the > max_fb_size, and we don't want to reserve too much as we would > want to reserve some low mmio space for PCI devices with 32-bit > BARs (if any). > > If the user runs Set-VMVideo and needs a framebuffer size > bigger than 64MB (IMO this is not a typical scenario in > practice), we have to use high mmio for hyperv_drm in the first > kernel, and the kdump kernel still suffers from the mmio > conflict between hyperv_drm and hv_pci. We encourage Gen1 VM > users to upgrade to Gen2 VMs to resolve the issue. Anyway, the > mmio conflict is inevitable for Gen1 VMs, if the max required > framebuffer size is bigger than 108MB (Note: > 128MB - VTPM_BASE_ADDRESS = 109.25, and the required framebuffer > size is always rounded up to 2MB). Question about Gen 1 VMs: If the Linux frame buffer driver moves the frame buffer somewhere other than the default location, and then the VM does a kexec/kdump, what does the legacy PCI graphic device BAR report as the frame buffer location? Does it *always* report 4G-128MB, or does it report the new location? I can run an experiment to find out, but maybe you've already done so and not reported that detail here. Michael

