/build-edk2-gvtd

Automatically Build GVT-d Ready OVMF and OpROM

Primary LanguageShellThe UnlicenseUnlicense

build-edk2-gvtd

Build EDK2 with Intel GVT-D Support

Tested Platforms

  • Intel Core 13900T ES Q0PV (AlderLake, Asrock Deskmini B660, PVE 8.0.4, Win11 23H2)
  • Intel Intel N100 (AlderLake-N, GMKtec NucBox G3, PVE 8.0.4, Win11 23H2)

Test reports on different platforms are welcomed, feel free to open new issues.

Prerequisites

  • git
  • docker
  • internet access
  • your own intel gop driver (which can be extracted with UEFI-BIOS-Updater from your Motherboard's BIOS image, which can be downloaded from here and here)

Usage

git clone git@github.com:cmd2001/build-edk2-gvtd.git
cd build-edk2-gvtd
sh ./init_edk2.sh
cp <intel gop driver efi> gop/IntelGopDriver.efi
sudo bash ./build_ovmf.sh
sudo bash ./build_oprom.sh

Now you have OVMF_CODE_4MB.fd, OVMF_CODE_4MB.secboot.fd and XXX.rom, XXX_GOP.rom in ./product. (where XXX.rom, XXX_GOP.rom is B660.rom, B660_GOP.rom as default)

The first two files contains a customized edk2 firmware supporting iGPU passthrough, you can copy them to /usr/share/pve-edk2-firmware and overwrite the original files from PVE.

If you are unpleasant about overwritting the edk2 firmware of PVE, you can copy XXX.rom to /usr/share/kvm/ and use this OpRom to achieve iGPU passthrough.

Then edit the configuration file of your VM, now you can boot your VM with integrated graphics passthrough and light your monitor.

Key Changes in VM Config

REMINDER: OS Type must be set to Linux and CPU Type must be set to HOST, otherwise the Windows guest system will not work after installing the driver from Intel.

Using Only OpRom (Recommended, Easier)

args: -set device.hostpci0.addr=02.0 -set device.hostpci0.x-igd-gms=6 -set device.hostpci0.x-igd-opregion=on
hostpci0: 0000:00:02,legacy-igd=1,romfile=XXX.rom

XXX.rom denotes the OpRom generated by build_oprom.sh (B660.rom as default).

Using customized edk2 firmware and OpROM (Fallback, with better capability and higher success rate)

args: -set device.hostpci0.addr=02.0 -set device.hostpci0.x-igd-gms=6 -set device.hostpci0.x-igd-opregion=on
hostpci0: 0000:00:02,legacy-igd=1,romfile=XXX_GOP.rom

XXX_GOP.rom should be placed in /usr/share/kvm/.

This repository uses a patched edk2 repository, which fixes a bug about ASSIGNED_IGD_PCI_BDSM_OFFSET from intel's vanilla patch. The bug could make iGPU use inappropriate memory region as stolen memory, causing a black or blink screen.

Now the customized edk2 firmware method and OpRom only method should do the same work.

Due to loading order of efis in OVMF image during QEMU-KVM runtime, this method (the method using only OpROM) may lead to a blurry screen, or just prevent screen from lighting up. In this case, please switch to previous method.

To dig deeper into this issue, it is caused by reserving stolen memory for iGPU at inappropriate address. As PVE tend to add OpRom used in the vm configuration to the tail of its own OVMF_CODE image, the IgdAssignmentDxe.efi from our OpRom, which reserves stolen memory region for iGPU, is executed after all xxxDxe.efis from OVMF_CODE, which is different from what happens when booting a real(physical) machine with iGPU.

In this case, as some xxxDxe.efis from OVMF_CODE may also allocate memory region for other virtual devices, the stolen memory reserved for iGPU may be allocated behind the address its expected to be, causing iGPU use inappropriate memory region(the memory region allocated for other devices) and a blurry or black screen.

This issue is most seen on 6th-10th gen Intel Core platform, as well as Atom/Embedded platform from same age(AppolloLake and GeminiLake). Currently there is no permanent solution to this issue. The only thing we can do is to switch to the previous method (to use a customized edk2 firmware and GOP-only OpROM) and wish for a good luck.

Note

  • If you have global internet access(in another word, you are not in China Mainland), comment out line 6-7 in Dockerfile.ovmf for faster download speed.

Reference