From e5d46dcc7d6846fcde892fa9c2d86b63c7b346c6 Mon Sep 17 00:00:00 2001 From: Jiaqing Zhao Date: Fri, 16 Jun 2023 10:40:00 +0000 Subject: [PATCH] hv: vpci: ignore PCI I/O BAR with non-zero upper 16 bits On x86 platform, the upper 16 bit of I/O BAR should be initialized to zero by BIOS. Howerever, some buggy BIOS still programs the upper 16 bits to non-zero, which causes error in check_pt_dev_pio_bars(). Since I/O BAR reprogramming by VM is currently unsupported, this patch ignores such I/O BARs when creating vpci devices to make VM boot. Tracked-On: #8373 Signed-off-by: Jiaqing Zhao Reviewed-by: Junjie Mao --- hypervisor/dm/vpci/pci_pt.c | 19 ++++++++++++++++++- hypervisor/include/arch/x86/asm/io.h | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index 58c2707f7..9f14bad8d 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -379,7 +379,24 @@ static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar) if (is_pci_reserved_bar(vbar)) { continue; } - mask = (is_pci_io_bar(vbar)) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; + + if (is_pci_io_bar(vbar)) { + if (lo & ~IO_SPACE_BITMASK) { + /* + * Some buggy x86 BIOS may program an invalid I/O BAR whose upper 16 bits are not zero. + * Such I/O BAR is not addressable on x86 platforms. Skip it when initializing the + * virtual PCI function as I/O BAR reprogramming in VM is currently unsupported. + */ + pr_warn("%s: %02x:%02x.%x: IO BAR%d value 0x%08x has invalid bits, IO_SPACE_BITMASK " + "is 0x%08x, Ignore this BAR in vdev", + __func__, vdev->bdf.bits.b, vdev->bdf.bits.d, vdev->bdf.bits.f, idx, lo, + IO_SPACE_BITMASK); + continue; + } + mask = PCI_BASE_ADDRESS_IO_MASK; + } else { + mask = PCI_BASE_ADDRESS_MEM_MASK; + } vbar->base_hpa = (uint64_t)lo & mask; if (is_pci_mem64lo_bar(vbar)) { diff --git a/hypervisor/include/arch/x86/asm/io.h b/hypervisor/include/arch/x86/asm/io.h index 42bf87bf3..9bf1f62ce 100644 --- a/hypervisor/include/arch/x86/asm/io.h +++ b/hypervisor/include/arch/x86/asm/io.h @@ -9,6 +9,9 @@ #include +/* X86 architecture only supports 16 bits IO space */ +#define IO_SPACE_BITMASK 0xffffU + /* Write 1 byte to specified I/O port */ static inline void pio_write8(uint8_t value, uint16_t port) {