MdeModulePkg/PciBusDxe: Fix Mem64 BAR handling in IsPciDeviceRejected()

IsPciDeviceRejected() masks BAR value with 0xFFFFFFF0 before testing
the type bits (2:1) that mark a 64-bit memory BAR, essentially clears
them, making the 64-bit BAR code path unreachable and treated as if
it were 32-bit.

The function rejects a device when BAR looks unprogrammed by comparing
if its size mask equals its value. When a 64-bit BAR is mistaken for a
32-bit one, only its lower part is compared, possibly leading a valid
BAR being falsely rejected. For example, a 2G BAR with size mask
0x80000000 at 0x180000000 matches and the device is dropped.

This code runs during light enumeration (PciEnumeratorLight), used when
PCI resources are already assigned by the platform (e.g. Xen HVM, where
hvmloader programs the BARs). The rejected device never receives a
PciIo handle, so no driver can bind to it. For example, a virtio-vga
with a 64-bit BAR vanishes under OVMF on Xen, leaving the guest with
no graphics output.

Fix by testing the type bits on the raw BAR value before masking.

Signed-off-by: Jiaqing Zhao <Zhao.Jiaqing@amd.com>
This commit is contained in:
Jiaqing Zhao 2026-06-18 16:27:06 +08:00 committed by mergify[bot]
parent 35b5565764
commit e3e93cf092

View file

@ -2921,13 +2921,12 @@ IsPciDeviceRejected (
//
// Mem Bar
//
Mask = 0xFFFFFFF0;
TestValue = TestValue & Mask;
Mask = 0xFFFFFFF0;
if ((TestValue & 0x07) == 0x04) {
//
// Mem64 or PMem64
//
TestValue = TestValue & Mask;
BarOffset += sizeof (UINT32);
if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {
//
@ -2942,6 +2941,7 @@ IsPciDeviceRejected (
//
// Mem32 or PMem32
//
TestValue = TestValue & Mask;
if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {
return TRUE;
}