qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 0/4] vfio/igd: remove incorrect IO BAR4 quirk


From: Tomita Moeko
Subject: [PATCH 0/4] vfio/igd: remove incorrect IO BAR4 quirk
Date: Thu, 23 Jan 2025 01:17:27 +0800

Based on experiments and reverse engineering about the mysterious IO
BAR4, it appears that the current quirk implementation is incorrect.
As discussed in a previous mail thread [1], current implementation
believes VBIOS is writing HPA of Data Stolen Memory (DSM) in GTT
entries, so it intercepts and writes (addr - Host BDSM + Guest BDSM)
instead, probably believes the addresses are hardcoded in VBIOS.

With disassembling a VBIOS of Intel Sandy/Ivy Bridge and Haswell [2]
(thankfully there is only a few 32-bit out instructions), VBIOS read
BDSM from pci config space, which is programmed by SeaBIOS [3] in
guest. That is to say, VBIOS actually writes GPA when programming GTT
initial entries, the current quirk is incorrect.

The change was tested on a Kaby Lake HD620 (Gen 9) by comparing GTT
entries read from MMIO BAR0 and IO BAR4.

This patchset also creates a new function vfio_config_quirk_setup()
for the config space quirk previously in vfio_probe_igd_bar4_quirk().
The OpRegion quirk in vfio_realize() will also be moved to it in a
later change, so that all the IGD-related quirks can be put in igd.c.

[1] 
https://lore.kernel.org/qemu-devel/b373a030-5ccf-418c-9213-865ddc6748fd@gmail.com/
[2] 
https://winraid.level1techs.com/t/offer-intel-sandy-ivy-bridge-and-haswell-vbios-modules/30272
[3] 
https://gitlab.com/qemu-project/seabios/-/blob/1.12-stable/src/fw/pciinit.c#L319-332

Related VBIOS disassembly:

# read BDSM
6498:   66 53                   push   %ebx
649a:   66 2e 83 3e 94 64 00    cmpl   $0x0,%cs:0x6494  # BDSM already read?
64a1:   74 07                   je     0x64aa
64a3:   66 2e a1 94 64          mov    %cs:0x6494,%eax 
64a8:   eb 0f                   jmp    0x64b9
64aa:   b8 5e 10                mov    $0x105e,%ax      # 5e == 5c + 2, that's 
why shl 16 later?
                                                    # ((2 << 11) + 0x5e)
64ad:   e8 55 05                call   0x6a05           # read config space via 
port cf8/cfc
64b0:   66 c1 e0 10             shl    $0x10,%eax       # eax << 16
64b4:   66 2e a3 94 64          mov    %eax,%cs:0x6494  # save BDSM
64b9:   66 5b                   pop    %ebx
64bb:   c3                      ret
# program single GTT entry, esi: addr, eax: data
6d16:   66 50                   push   %eax
6d18:   52                      push   %dx
6d19:   2e 8b 16 4a e4          mov    %cs:-0x1bb6,%dx  # saved MMIO_Index port
6d1e:   66 96                   xchg   %eax,%esi
6d20:   66 ef                   out    %eax,(%dx)       # write MMIO_Index
6d22:   2e 8b 16 4c e4          mov    %cs:-0x1bb4,%dx  # saved MMIO_Data port
6d27:   66 96                   xchg   %eax,%esi
6d29:   66 83 c8 01             or     $0x1,%eax        # set valid bit
6d2d:   66 ef                   out    %eax,(%dx)       # write MMIO_Data
6d2f:   5a                      pop    %dx
6d30:   66 58                   pop    %eax
6d32:   c3                      ret
# program GTT entries, esi: entry addr, eax: page addr
e929:   51                      push   %cx
e92a:   e8 6b 7b                call   0x6498       # read BDSM
e92d:   25 00 e0                and    $0xe000,%ax
e930:   66 83 c8 01             or     $0x1,%eax    # valid bit
e934:   66 be 01 00 00 00       mov    $0x1,%esi    # gtt access bit in addr
e93a:   e8 d9 83                call   0x6d16       # single entry routine
e93d:   66 83 c6 04             add    $0x4,%esi    # next entry
e941:   66 05 00 10 00 00       add    $0x1000,%eax # next page
e947:   e2 f1                   loop   0xe93a
e949:   59                      pop    %cx
e94a:   c3                      ret

Observed layout of the undocumented MMIO_Index register:
 31                                                   2   1      0
+-------------------------------------------------------------------+
|                        Offset                        | Rsvd | Sel |
+-------------------------------------------------------------------+
- Offset: Byte offset in specified region, 4-byte aligned.
- Sel: Region selector
       0: MMIO register region (first half of MMIO BAR0)
       1: GTT region (second half of MMIO BAR0). Pre Gen11 only.

Tomita Moeko (4):
  vfio/igd: remove GTT write quirk in IO BAR 4
  vfio/pci: add placeholder for device-specific config space quirks
  vfio/igd: refactor vfio_probe_igd_bar4_quirk() into pci config quirk
  vfio/igd: do not include GTT stolen size in etc/igd-bdsm-size

 hw/vfio/igd.c        | 247 ++++---------------------------------------
 hw/vfio/pci-quirks.c |  11 +-
 hw/vfio/pci.c        |   4 +
 hw/vfio/pci.h        |   3 +-
 4 files changed, 35 insertions(+), 230 deletions(-)

-- 
2.45.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]