On Wed, 17 Jun 2026 18:06:37 +0800
Tomita Moeko <[email protected]> wrote:
> This series fixes the regression that on IGD passthrough with legacy
> BIOS boot and VBIOS, the screen is garbled during BIOS POST and GRUB
> (which uses standard VGA output routines), starting from QEMU 10.0.
> Though the kernel i915 driver still works, it reports an error about
> the initial GTT programmed by VBIOS is using invalid address.
>
> i915 0000:00:02.0: [drm] *ERROR* Initial plane programming using invalid
> range, dma_addr=0x00000000db200000 ((null)
> [0x00000000baf00000-0x00000000beefffff])
>
> With the help of AI disassembling the VBIOS image dumped from host, it
> is found that the VBIOS itself implements a routine like:
>
> uint32_t get_BDSM() {
> static uint32_t saved = 0;
> if (saved != 0) {
> return saved;
> }
> return read_pci_config(BDSM_REG);
> }
>
> And the saved value is not cleared after initialization. Given that IGD
> devices don't have a real ROM BAR, the VBIOS image read by default from
> host is actually the VBIOS shadow RAM region, containing host-side
> modifications like the saved BDSM value above during POST. When the
> image is executed in guest, it still uses the saved host BDSM (HPA)
> instead of the value programmed by SeaBIOS in config space (GPA). This
> address mismatch leads to the garbled screen and i915 error.
>
> The previous solution, c4c45e943e51 ("vfio/pci: Intel graphics legacy
> mode assignment"), adjusts GTT entry addresses to (addr - host BDSM +
> guest BDSM) to workaround that. But it is removed in 5aed8b0f0be2
> ("vfio/igd: Remove GTT write quirk in IO BAR 4") due to inconsistent
> values in MMIO BAR0 and IO BAR4. Considering it's unsafe to expose HPA
> to guest, a ROM quirk clearing the saved value in VBIOS image is
> introduced to fix the issue.
>
> During debugging, it is also found that IGD VBIOS ROM doesn't always
> match the actual IGD device ID, due to the fact that IGD of the same
> CPU family has multiple device IDs but shares the same ROM image.
> However, SeaBIOS checks the device ID strictly and refuses to run if
> IDs does not match. Currently only the default path, reading ROM from
> kernel patches the device ID, but the romfile path doesn't. So the ROM
> ID patching logic is also refactored in this patch series to also handle
> the romfile path.
>
> These changes are tested on Haswell platform with legacy BIOS boot, by
> K S Maan. Thanks to K S Maan for continuous help on locating and testing
> the issue!
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3093
> Reported-by: K S Maan <[email protected]>
>
> Changelog:
> v3:
> * Refactor ROM checksum calculation and patching logic as Alex's comment
> * Fix boundary checks as comments in v2.
> Link:
> https://lore.kernel.org/all/[email protected]/t
>
> v2:
> * New patch 2/7 to fix regression with EFI option ROMs
> * Refine logic in ROM ID and checksum patching
> * Reorder patch 4 and 5 for cleaner bisection
> * Address comments from v1
> Link:
> https://lore.kernel.org/all/[email protected]/t
>
> Tomita Moeko (7):
> hw/pci: Recalculate option ROM checksum before patching ID
> hw/pci: Skip EFI option ROM in pci_patch_ids()
> hw/pci: Introduce rom_need_patch_id flag in PCIDevice
> hw/pci: Promote pci_patch_ids() to public pci_rom_patch_ids()
> vfio/igd: Toggle rom_need_patch_id flag on IGD devices
> vfio/pci: Use pci_rom_patch_ids() for IGD ROM ID patching
> vfio/igd: Clear saved BDSM in legacy VBIOS ROM at load time
>
> hw/pci/pci.c | 57 ++++++++++------
> hw/vfio/igd-stubs.c | 5 ++
> hw/vfio/igd.c | 132 ++++++++++++++++++++++++++++++++++--
> hw/vfio/pci-quirks.c | 5 ++
> hw/vfio/pci.c | 33 ++-------
> hw/vfio/pci.h | 3 +
> hw/vfio/trace-events | 1 +
> include/hw/pci/pci.h | 3 +
> include/hw/pci/pci_device.h | 1 +
> 9 files changed, 186 insertions(+), 54 deletions(-)
Reviewed-by: Alex Williamson <[email protected]>