linux/drivers/hv
Dexuan Cui f2cbbddc84 Drivers: hv: vmbus: Improve the logic of reserving fb_mmio on Gen2 VMs
[ Upstream commit 016a25e4b0 ]

If vmbus_reserve_fb() in the kdump/kexec kernel fails to properly reserve
the framebuffer MMIO range (which is below 4GB) due to a Gen2 VM's
screen.lfb_base being zero [1], there is an MMIO conflict between the
drivers hyperv-drm and pci-hyperv: when the driver pci-hyperv's
hv_allocate_config_window() calls vmbus_allocate_mmio() to get an
MMIO range, typically it gets a 32-bit MMIO range that overlaps with the
framebuffer MMIO range, and later hv_pci_enter_d0() fails with an
error message "PCI Pass-through VSP failed D0 Entry with status" since
the host thinks that PCI devices must not use MMIO space that the
host has assigned to the framebuffer.

This is especially an issue if pci-hyperv is built-in and hyperv-drm is
built as a module. Consequently, the kdump/kexec kernel fails to detect
PCI devices via pci-hyperv, and may fail to mount the root file system,
which may reside in a NVMe disk. The issue described here has existed
for SR-IOV VF NICs since day one of the pci-hyperv driver, and has been
worked around on x64 when possible. With the recent introduction of
ARM64 VMs that boot from NVMe, there is no workaround, so we need a
formal fix.

On Gen2 VMs, if the screen.lfb_base is 0 in the kdump/kexec kernel [1],
fall back to the low MMIO base, which should be equal to the framebuffer
MMIO base [2] (the statement is true according to my testing on x64
Windows Server 2016, and on x64 and ARM64 Windows Server 2025 and on
Azure. I checked with the Hyper-V team and they said the statement should
continue to be true for Gen2 VMs). In the first kernel, screen.lfb_base
is not 0; if the user specifies a very high resolution, it's not enough
to only reserve 8MB: let's always reserve half of the space below 4GB,
but cap the reservation to 128MB, which is the required framebuffer size
of the highest resolution 7680*4320 supported by Hyper-V.

While at it, fix the comparison "end > VTPM_BASE_ADDRESS" by changing
the > to >=. Here the 'end' is an inclusive end (typically, it's
0xFFFF_FFFF for the low MMIO range).

Note: vmbus_reserve_fb() now also reserves an MMIO range at the beginning
of the low MMIO range on CVMs, which have no framebuffers (the
'screen.lfb_base' in vmbus_reserve_fb() is 0 for CVMs), just in case the
host might treat the beginning of the low MMIO range specially [3]. BTW,
the OpenHCL kernel is not affected by the change, because that kernel
boots with DeviceTree rather than ACPI (so vmbus_reserve_fb() won't run
there), and there is no framebuffer device for that kernel.

Note: normally Gen1 VMs don't have the MMIO conflict issue because the
framebuffer MMIO range (which is hardcoded to base=4GB-128MB and
size=64MB for Gen1 VMs by the host) is always reported via the legacy PCI
graphics device's BAR, so the kdump/kexec kernel can reserve the 64MB
MMIO range; however, if the VM is configured to use a very high resolution
and the required framebuffer size exceeds 64MB (AFAIK, in practice, this
isn't a typical configuration by users), the hyperv-drm driver may need to
allocate an MMIO range above 4GB and change the framebuffer MMIO location
to the allocated MMIO range -- in this case, there can still be issues [4]
which can't be easily fixed: any possible affected Gen1 users would have
to use a resolution whose framebuffer size is <= 64MB, or switch to Gen2
VMs.

[1] https://lore.kernel.org/all/SA1PR21MB692176C1BC53BFC9EAE5CF8EBF51A@SA1PR21MB6921.namprd21.prod.outlook.com/
[2] https://lore.kernel.org/all/SA1PR21MB69218F955B62DFF62E3E88D2BF222@SA1PR21MB6921.namprd21.prod.outlook.com/
[3] https://lore.kernel.org/all/SN6PR02MB415726B17D5A6027CD1717E8D4342@SN6PR02MB4157.namprd02.prod.outlook.com/
[4] https://lore.kernel.org/all/SA1PR21MB69213486F821CA5A2C793C81BF342@SA1PR21MB6921.namprd21.prod.outlook.com/

Fixes: 4daace0d8c ("PCI: hv: Add paravirtual PCI front-end for Microsoft Hyper-V VMs")
CC: stable@vger.kernel.org
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Tested-by: Krister Johansen <kjlx@templeofstupid.com>
Tested-by: Matthew Ruffell <matthew.ruffell@canonical.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2026-07-04 13:39:40 +02:00
..
channel.c Drivers: hv: vmbus: Fix handling of messages with transaction ID of zero 2022-06-09 10:23:07 +02:00
channel_mgmt.c Drivers: hv: vmbus: Add utility function for querying ring size 2025-07-10 15:57:36 +02:00
connection.c Drivers: vmbus: Check for channel allocation before looking up relids 2023-04-13 16:48:17 +02:00
hv.c drivers: hv: Create a consistent pattern for checking Hyper-V hypercall status 2021-04-21 09:49:19 +00:00
hv_balloon.c Drivers: hv: balloon: Support status report for larger page sizes 2022-09-05 10:30:04 +02:00
hv_common.c drivers: hv: Decouple Hyper-V clock/timer code from VMbus drivers 2021-07-19 09:24:28 +00:00
hv_debugfs.c hv_debugfs: Make hv_debug_root static 2020-04-04 17:47:43 +01:00
hv_fcopy.c Drivers: hv: vmbus: Copy packets sent by Hyper-V out of the ring buffer 2021-05-14 17:37:46 +00:00
hv_kvp.c hv: utils: handle and propagate errors in kvp_register 2026-07-04 13:39:40 +02:00
hv_snapshot.c Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet 2025-01-09 13:28:34 +01:00
hv_trace.c hv: add SPDX license to trace 2018-03-28 13:24:56 +02:00
hv_trace.h Drivers: hv: vmbus: Drivers: hv: vmbus: Introduce CHANNELMSG_MODIFYCHANNEL_RESPONSE 2021-04-18 13:03:11 +00:00
hv_trace_balloon.h hv_balloon: trace post_status 2018-03-06 09:57:17 -08:00
hv_util.c Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet 2025-01-09 13:28:34 +01:00
hv_utils_transport.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 280 2019-06-05 17:36:36 +02:00
hv_utils_transport.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 280 2019-06-05 17:36:36 +02:00
hyperv_vmbus.h Drivers: hv: vmbus: Add utility function for querying ring size 2025-07-10 15:57:36 +02:00
Kconfig hv: utils: add PTP_1588_CLOCK to Kconfig to fix build 2022-04-08 14:22:46 +02:00
Makefile Drivers: hv: Move Hyper-V extended capability check to arch neutral code 2021-06-05 10:22:34 +00:00
ring_buffer.c video: hyperv_fb: Avoid taking busy spinlock on panic path 2022-12-31 13:14:39 +01:00
vmbus_drv.c Drivers: hv: vmbus: Improve the logic of reserving fb_mmio on Gen2 VMs 2026-07-04 13:39:40 +02:00