* [PATCH v4 0/4] vfio/igd: Fix garbled screen on IGD passthrough with legacy VBIOS
@ 2026-07-01 18:20 Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 1/4] hw/pci: Introduce romfile_fixup hook in PCIDevice Tomita Moeko
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Tomita Moeko @ 2026-07-01 18:20 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Williamson, Cédric Le Goater, Michael S. Tsirkin,
Tomita Moeko, K S Maan
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 <kirandeepmaan45@gmail.com>
Changelog:
v4:
* Reworked per review feedback to keep IGD-specific workarounds out of
the generic PCI code. Instead of recalculating the checksum in
hw/pci/pci.c, a single generic romfile_fixup hook is added for device-
specific ROM patching. Now both kernel ROM BAR and romfile paths share
the same quirk, so the saved BDSM in user-provided romfile will also
get cleared.
* Reduced from 7 to 4 patches.
Link: https://lore.kernel.org/all/20260617100646.28326-1-tomitamoeko@gmail.com/t
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/20260608134559.23971-1-tomitamoeko@gmail.com/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/20260603173355.36121-1-tomitamoeko@gmail.com/t
Tomita Moeko (4):
hw/pci: Introduce romfile_fixup hook in PCIDevice
vfio/igd: Refactor option ROM patching
vfio/igd: Setup romfile_fixup hook
vfio/igd: Clear saved BDSM in legacy VBIOS ROM at load time
hw/pci/pci.c | 4 ++
hw/vfio/igd-stubs.c | 5 ++
hw/vfio/igd.c | 128 ++++++++++++++++++++++++++++++++++++
hw/vfio/pci-quirks.c | 5 ++
hw/vfio/pci.c | 30 +--------
hw/vfio/pci.h | 3 +
hw/vfio/trace-events | 1 +
include/hw/pci/pci_device.h | 1 +
8 files changed, 148 insertions(+), 29 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/4] hw/pci: Introduce romfile_fixup hook in PCIDevice
2026-07-01 18:20 [PATCH v4 0/4] vfio/igd: Fix garbled screen on IGD passthrough with legacy VBIOS Tomita Moeko
@ 2026-07-01 18:20 ` Tomita Moeko
2026-07-01 20:58 ` Michael S. Tsirkin
2026-07-01 18:20 ` [PATCH v4 2/4] vfio/igd: Refactor option ROM patching Tomita Moeko
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Tomita Moeko @ 2026-07-01 18:20 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Williamson, Cédric Le Goater, Michael S. Tsirkin,
Tomita Moeko, K S Maan
Some devices, such as VFIO IGD passthrough, require device-specific
fixups on the romfile provided by user. Add an optional romfile_fixup
hook to PCIDevice. When set, it is invoked from pci_add_option_rom()
right after the image is loaded, receiving the ROM buffer and its
size. This provides a place to post-process a loaded romfile without
leaking device-specific logic into the generic PCI core.
Reported-by: K S Maan <kirandeepmaan45@gmail.com>
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
---
hw/pci/pci.c | 4 ++++
include/hw/pci/pci_device.h | 1 +
2 files changed, 5 insertions(+)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4298adf5a0..7d30d44411 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2632,6 +2632,10 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
/* Only the default rom images will be patched (if needed). */
pci_patch_ids(pdev, ptr, size);
}
+
+ if (pdev->romfile_fixup) {
+ pdev->romfile_fixup(pdev, ptr, size);
+ }
}
pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index 5cac6e1688..a65e77018c 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -159,6 +159,7 @@ struct PCIDevice {
bool has_rom;
MemoryRegion rom;
int32_t rom_bar;
+ void (*romfile_fixup)(PCIDevice *pdev, uint8_t *ptr, uint32_t size);
/* INTx routing notifier */
PCIINTxRoutingNotifier intx_routing_notifier;
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/4] vfio/igd: Refactor option ROM patching
2026-07-01 18:20 [PATCH v4 0/4] vfio/igd: Fix garbled screen on IGD passthrough with legacy VBIOS Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 1/4] hw/pci: Introduce romfile_fixup hook in PCIDevice Tomita Moeko
@ 2026-07-01 18:20 ` Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 3/4] vfio/igd: Setup romfile_fixup hook Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 4/4] vfio/igd: Clear saved BDSM in legacy VBIOS ROM at load time Tomita Moeko
3 siblings, 0 replies; 6+ messages in thread
From: Tomita Moeko @ 2026-07-01 18:20 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Williamson, Cédric Le Goater, Michael S. Tsirkin,
Tomita Moeko, K S Maan
Currently the IGD-specific option ROM patching logic is embedded in
vfio_pci_load_rom() rather than igd.c where IGD-specific code lives.
Move this logic into a dedicated vfio_igd_legacy_rom_quirk() in igd.c.
The refactored quirk patches the device ID and checksum on Gen 6~9
devices with legacy VBIOS as option ROM. A new trace event
vfio_pci_igd_vbios_patched is also introduced.
Arguments of vfio_igd_legacy_rom_quirk() are aligned with romfile_fixup
of PCIDevice so that same logic can be reused on romfile later.
Reported-by: K S Maan <kirandeepmaan45@gmail.com>
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
---
hw/vfio/igd-stubs.c | 5 +++++
hw/vfio/igd.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
hw/vfio/pci-quirks.c | 5 +++++
hw/vfio/pci.c | 30 +--------------------------
hw/vfio/pci.h | 3 +++
hw/vfio/trace-events | 1 +
6 files changed, 63 insertions(+), 29 deletions(-)
diff --git a/hw/vfio/igd-stubs.c b/hw/vfio/igd-stubs.c
index f7687d9091..29110f7568 100644
--- a/hw/vfio/igd-stubs.c
+++ b/hw/vfio/igd-stubs.c
@@ -18,3 +18,8 @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
{
return true;
}
+
+void vfio_igd_legacy_rom_quirk(PCIDevice *pdev, uint8_t *ptr, uint32_t size)
+{
+ return;
+}
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index e091f21b6a..f597218164 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -724,3 +724,51 @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
return vfio_pci_igd_config_quirk(vdev, errp);
}
+
+void vfio_igd_legacy_rom_quirk(PCIDevice *pdev, uint8_t *ptr, uint32_t size)
+{
+ VFIOPCIDevice *vdev = VFIO_PCI_DEVICE(pdev);
+ int gen;
+ uint16_t pcir_offset;
+ uint8_t checksum = 0;
+ uint32_t i;
+
+ if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
+ !vfio_is_vga(vdev) || !vdev->vga) {
+ return;
+ }
+
+ /* Only Gen 6~9 devices have legacy VBIOS as Option ROM */
+ gen = igd_gen(vdev);
+ if (gen < 6 || gen > 9) {
+ return;
+ }
+
+ if (pci_get_word(ptr) != 0xaa55) {
+ return;
+ }
+
+ /* Must be a legacy ROM */
+ pcir_offset = pci_get_word(ptr + 0x18);
+ if (pcir_offset + 0x14 >= size || memcmp(ptr + pcir_offset, "PCIR", 4) ||
+ pci_get_byte(ptr + pcir_offset + 0x14) != 0x00) {
+ return;
+ }
+
+ /*
+ * Patch device ID as multiple IGD devices share the same rom with possible
+ * non-matching IDs.
+ */
+ pci_set_word(ptr + pcir_offset + 6, vdev->device_id);
+
+ /*
+ * IGD roms are known to have bogus checksums. No matter we changed the
+ * device ID or not, we need to recalculate the checksum and patch it.
+ */
+ for (i = 0; i < size; i++) {
+ checksum += ptr[i];
+ }
+ ((uint8_t *)ptr)[6] -= checksum;
+
+ trace_vfio_pci_igd_vbios_patched(vdev->vbasedev.name);
+}
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index bccf31751f..496a79a3ca 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1592,3 +1592,8 @@ bool vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp)
return true;
}
+
+void vfio_rom_quirk_setup(VFIOPCIDevice *vdev)
+{
+ vfio_igd_legacy_rom_quirk(PCI_DEVICE(vdev), vdev->rom, vdev->rom_size);
+}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 9c06b25e63..d321e6160a 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1084,35 +1084,7 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
}
}
- /*
- * Test the ROM signature against our device, if the vendor is correct
- * but the device ID doesn't match, store the correct device ID and
- * recompute the checksum. Intel IGD devices need this and are known
- * to have bogus checksums so we can't simply adjust the checksum.
- */
- if (pci_get_word(vdev->rom) == 0xaa55 &&
- pci_get_word(vdev->rom + 0x18) + 8 < vdev->rom_size &&
- !memcmp(vdev->rom + pci_get_word(vdev->rom + 0x18), "PCIR", 4)) {
- uint16_t vid, did;
-
- vid = pci_get_word(vdev->rom + pci_get_word(vdev->rom + 0x18) + 4);
- did = pci_get_word(vdev->rom + pci_get_word(vdev->rom + 0x18) + 6);
-
- if (vid == vdev->vendor_id && did != vdev->device_id) {
- int i;
- uint8_t csum, *data = vdev->rom;
-
- pci_set_word(vdev->rom + pci_get_word(vdev->rom + 0x18) + 6,
- vdev->device_id);
- data[6] = 0;
-
- for (csum = 0, i = 0; i < vdev->rom_size; i++) {
- csum += data[i];
- }
-
- data[6] = -csum;
- }
- }
+ vfio_rom_quirk_setup(vdev);
}
/* "Raw" read of underlying config space. */
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index c3a1f53d35..620baddda2 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -251,10 +251,13 @@ void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr);
void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr);
void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
bool vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
+void vfio_rom_quirk_setup(VFIOPCIDevice *vdev);
void vfio_quirk_reset(VFIOPCIDevice *vdev);
VFIOQuirk *vfio_quirk_alloc(int nr_mem);
+
void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr);
bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp);
+void vfio_igd_legacy_rom_quirk(PCIDevice *pdev, uint8_t *ptr, uint32_t size);
extern const PropertyInfo qdev_prop_nv_gpudirect_clique;
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 2049159015..7dc334ccb3 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -90,6 +90,7 @@ vfio_pci_igd_bar4_write(const char *name, uint32_t index, uint32_t data, uint32_
vfio_pci_igd_bdsm_enabled(const char *name, int size) "%s %dMB"
vfio_pci_igd_host_bridge_enabled(const char *name) "%s"
vfio_pci_igd_lpc_bridge_enabled(const char *name) "%s"
+vfio_pci_igd_vbios_patched(const char *name) "%s"
# listener.c
vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "iommu %s @ 0x%"PRIx64" - 0x%"PRIx64
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 3/4] vfio/igd: Setup romfile_fixup hook
2026-07-01 18:20 [PATCH v4 0/4] vfio/igd: Fix garbled screen on IGD passthrough with legacy VBIOS Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 1/4] hw/pci: Introduce romfile_fixup hook in PCIDevice Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 2/4] vfio/igd: Refactor option ROM patching Tomita Moeko
@ 2026-07-01 18:20 ` Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 4/4] vfio/igd: Clear saved BDSM in legacy VBIOS ROM at load time Tomita Moeko
3 siblings, 0 replies; 6+ messages in thread
From: Tomita Moeko @ 2026-07-01 18:20 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Williamson, Cédric Le Goater, Michael S. Tsirkin,
Tomita Moeko, K S Maan
Install vfio_igd_legacy_rom_quirk() as the PCIDevice romfile_fixup hook
when romfile is set so that a romfile-supplied VBIOS receives the same
IGD fixup as the image read from the kernel ROM BAR.
Reported-by: K S Maan <kirandeepmaan45@gmail.com>
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
---
hw/vfio/igd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index f597218164..6fa8b26201 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -610,6 +610,10 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
goto error;
}
+ if (pdev->romfile) {
+ pdev->romfile_fixup = vfio_igd_legacy_rom_quirk;
+ }
+
/*
* ASLS (OpRegion address) is read-only, emulated
* It contains HPA, guest firmware need to reprogram it with GPA.
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 4/4] vfio/igd: Clear saved BDSM in legacy VBIOS ROM at load time
2026-07-01 18:20 [PATCH v4 0/4] vfio/igd: Fix garbled screen on IGD passthrough with legacy VBIOS Tomita Moeko
` (2 preceding siblings ...)
2026-07-01 18:20 ` [PATCH v4 3/4] vfio/igd: Setup romfile_fixup hook Tomita Moeko
@ 2026-07-01 18:20 ` Tomita Moeko
3 siblings, 0 replies; 6+ messages in thread
From: Tomita Moeko @ 2026-07-01 18:20 UTC (permalink / raw)
To: qemu-devel
Cc: Alex Williamson, Cédric Le Goater, Michael S. Tsirkin,
Tomita Moeko, K S Maan
IGD does not come with a ROM BAR [1], the ROM BAR read by default from
kernel is actually the host VBIOS shadow RAM region that contains host
modifications on boot. With AI-assisted reverse engineering on VBIOS
binaries, it is observed that VBIOS saves BDSM register value on first
access and uses saved value if present.
When the image is executed in guest, since there is already a saved HPA
in VBIOS, it keeps using that value instead of the GPA programmed by
SeaBIOS in BDSM register in PCI config space, causing VBIOS to program
GTT entries with wrong address, resulting in garbled output in BIOS
POST and the error below detected by i915 driver.
i915 0000:00:02.0: [drm] *ERROR* Initial plane programming using invalid range, dma_addr=0x00000000db200000 ((null) [0x00000000baf00000-0x00000000beefffff])
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. It searches the BDSM
accessor routine by matching a 19-byte signature anchored on the unique
`mov $0x105e,%ax` instruction, then locate the offset of saved BDSM and
clears it. This makes the routine fall through to the PCI config read
on the first call inside the guest.
[1] 3.5.15, 4th Generation Intel Core Processor Family Datasheet Vol. 2
https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/4th-gen-core-family-desktop-vol-2-datasheet.pdf
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3093
Reported-by: K S Maan <kirandeepmaan45@gmail.com>
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
---
hw/vfio/igd.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 6fa8b26201..9a2f2a3c73 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -729,11 +729,81 @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
return vfio_pci_igd_config_quirk(vdev, errp);
}
+/*
+ * IGD ROM BAR read from kernel is actually the host VBIOS shadow RAM region,
+ * which contains host modifications. In Gen 6-9 VBIOS, the routine below is
+ * used to get BDSM value when programming the initial GTT.
+ * xx xx xx xx v: .long ? # saved value
+ * 66 53 push %ebx
+ * 66 2e 83 3e xx xx 00 cmpl $0x0,%cs:v # is saved value empty?
+ * 74 07 je 1f # if zero, go compute
+ * 66 2e a1 xx xx mov %cs:v,%eax # else return saved value
+ * eb 0f jmp 2f
+ * b8 5e 10 1: mov $0x105e,%ax # dev 00:02.0, offset 5E
+ * e8 xx xx call pci_read_cfg_word
+ * 66 c1 e0 10 shl $0x10,%eax # left shift 16 bits
+ * 66 2e a3 xx xx mov %eax,%cs:v # save the result
+ * 66 5b 2: pop %ebx
+ * c3 ret
+ * When running the VBIOS in guest, saved value still reflects the host stolen
+ * memory base address, which is not correct in guest. So we need to patch the
+ * VBIOS to clear the saved value.
+ *
+ * The unique 19-byte starts at `cmpl $0,%cs:v` and ends at `mov $0x105e,%ax`
+ * anchors the match to the routine. Both `cs:` displacements must reference
+ * the same offset.
+ */
+static int igd_vbios_find_saved_bdsm(const uint8_t *rom, size_t rom_size,
+ uint16_t *bdsm_offset)
+{
+ static const uint8_t start[] = { 0x66, 0x2e, 0x83, 0x3e };
+ static const uint8_t middle[] = { 0x00, 0x74, 0x07, 0x66, 0x2e, 0xa1 };
+ static const uint8_t end[] = { 0xeb, 0x0f, 0xb8, 0x5e, 0x10 };
+ uint16_t val;
+ size_t i;
+ bool found = false;
+
+ if (rom_size < 19) {
+ return -ENOENT;
+ }
+
+ for (i = 0; i + 19 <= rom_size; i++) {
+ if (memcmp(rom + i, start, sizeof(start)) != 0 ||
+ memcmp(rom + i + 6, middle, sizeof(middle)) != 0 ||
+ memcmp(rom + i + 14, end, sizeof(end)) != 0) {
+ continue;
+ }
+
+ /* same saved value address? */
+ if (rom[i + 4] != rom[i + 12] || rom[i + 5] != rom[i + 13]) {
+ continue;
+ }
+
+ if (found) {
+ return -EEXIST;
+ }
+
+ val = rom[i + 4] | ((uint16_t)rom[i + 5] << 8);
+ if (val + sizeof(uint32_t) <= rom_size) {
+ *bdsm_offset = val;
+ found = true;
+ }
+ }
+
+ if (!found) {
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
void vfio_igd_legacy_rom_quirk(PCIDevice *pdev, uint8_t *ptr, uint32_t size)
{
VFIOPCIDevice *vdev = VFIO_PCI_DEVICE(pdev);
int gen;
uint16_t pcir_offset;
+ int ret;
+ uint16_t bdsm_offset = 0;
uint8_t checksum = 0;
uint32_t i;
@@ -765,6 +835,12 @@ void vfio_igd_legacy_rom_quirk(PCIDevice *pdev, uint8_t *ptr, uint32_t size)
*/
pci_set_word(ptr + pcir_offset + 6, vdev->device_id);
+ /* Search and clear the saved BDSM value */
+ ret = igd_vbios_find_saved_bdsm(ptr, size, &bdsm_offset);
+ if (ret == 0) {
+ memset(ptr + bdsm_offset, 0, sizeof(uint32_t));
+ }
+
/*
* IGD roms are known to have bogus checksums. No matter we changed the
* device ID or not, we need to recalculate the checksum and patch it.
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 1/4] hw/pci: Introduce romfile_fixup hook in PCIDevice
2026-07-01 18:20 ` [PATCH v4 1/4] hw/pci: Introduce romfile_fixup hook in PCIDevice Tomita Moeko
@ 2026-07-01 20:58 ` Michael S. Tsirkin
0 siblings, 0 replies; 6+ messages in thread
From: Michael S. Tsirkin @ 2026-07-01 20:58 UTC (permalink / raw)
To: Tomita Moeko; +Cc: qemu-devel, Alex Williamson, Cédric Le Goater, K S Maan
On Thu, Jul 02, 2026 at 02:20:32AM +0800, Tomita Moeko wrote:
> Some devices, such as VFIO IGD passthrough, require device-specific
> fixups on the romfile provided by user. Add an optional romfile_fixup
> hook to PCIDevice. When set, it is invoked from pci_add_option_rom()
> right after the image is loaded, receiving the ROM buffer and its
> size. This provides a place to post-process a loaded romfile without
> leaking device-specific logic into the generic PCI core.
>
> Reported-by: K S Maan <kirandeepmaan45@gmail.com>
> Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
fine by me:
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> hw/pci/pci.c | 4 ++++
> include/hw/pci/pci_device.h | 1 +
> 2 files changed, 5 insertions(+)
>
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 4298adf5a0..7d30d44411 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -2632,6 +2632,10 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
> /* Only the default rom images will be patched (if needed). */
> pci_patch_ids(pdev, ptr, size);
> }
> +
> + if (pdev->romfile_fixup) {
> + pdev->romfile_fixup(pdev, ptr, size);
> + }
> }
>
> pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
> diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
> index 5cac6e1688..a65e77018c 100644
> --- a/include/hw/pci/pci_device.h
> +++ b/include/hw/pci/pci_device.h
> @@ -159,6 +159,7 @@ struct PCIDevice {
> bool has_rom;
> MemoryRegion rom;
> int32_t rom_bar;
> + void (*romfile_fixup)(PCIDevice *pdev, uint8_t *ptr, uint32_t size);
>
> /* INTx routing notifier */
> PCIINTxRoutingNotifier intx_routing_notifier;
> --
> 2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-01 20:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-01 18:20 [PATCH v4 0/4] vfio/igd: Fix garbled screen on IGD passthrough with legacy VBIOS Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 1/4] hw/pci: Introduce romfile_fixup hook in PCIDevice Tomita Moeko
2026-07-01 20:58 ` Michael S. Tsirkin
2026-07-01 18:20 ` [PATCH v4 2/4] vfio/igd: Refactor option ROM patching Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 3/4] vfio/igd: Setup romfile_fixup hook Tomita Moeko
2026-07-01 18:20 ` [PATCH v4 4/4] vfio/igd: Clear saved BDSM in legacy VBIOS ROM at load time Tomita Moeko
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.