iGPU PCI passthrough: new experimental packages need testers
-
DO NOT TEST THIS IN PRODUCTION
I did a Proof-of-Concept to improve the iGPU passthrough situation in the case where the vbios is not in the ROM BAR. This would usually fail in the guest because the guest
amdgpuori915driver would not be able to find the vbios.
I would like to share this PoC with you to gather feedback / testing.
This is not at all a production ready solution, as you will see with the manual steps which are needed to test this.Who should test this?
If you have an host with an iGPU, and the usual 8.3 PCI passthrough procedure described at https://docs.xcp-ng.org/compute/#pci-passthrough does not work because the guest
dmesgprints something likeInvalid PCI ROM header signature: expecting 0xaa55, got 0x4556or
Failed to find VBIOS tables (VBT)or
Unable to locate a BIOS ROMWhat has been tested so far
I only tested on an
AMD Ryzen Embedded V2748 with Radeon Graphicsembedded APU system with aRadeon RX Vega seriesintegrated GPU (PCI vendor id 1002 PCI device id 1636). With this config, I tested that the guest VM was able to correctly probe the GPU with theamgdpudriver.How to test
- Install a brand new XCP-ng 8.3 on a test host (or make sure you are up to date with latest 8.3 packages on your test host)
- Configure XCP-ng user repositories:
wget https://koji.xcp-ng.org/repos/user/8/8.3/xcpng-users.repo -O /etc/yum.repos.d/xcpng-users.repo- Update your system with the iGPU PoC packages
yum update --enablerepo=xcp-ng-ysionneau1- it will prompt you about importing a new GPG key
- it should install the following packages:
============================================================================================================================================================================================================================================================================================================================= Package Arch Version Repository Size ============================================================================================================================================================================================================================================================================================================================= Updating: edk2 x86_64 20220801-1.7.11.3~romtest.2.xcpng8.3 xcp-ng-ysionneau1 3.0 M forkexecd x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 2.5 M message-switch x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 4.6 M qcow-stream-tool x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 1.4 M qemu x86_64 2:4.2.1-5.2.18.1.0.fixrom.1.xcpng8.3 xcp-ng-ysionneau1 16 M rrdd-plugins x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 9.9 M sm-cli x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 4.9 M squeezed x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 1.9 M varstored-guard x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 5.0 M vhd-tool x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 5.0 M wsproxy x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 1.1 M xapi-core x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 30 M xapi-nbd x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 3.1 M xapi-rrd2csv x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 3.0 M xapi-storage-script x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 2.5 M xapi-tests x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 5.0 M xapi-xe x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 1.5 M xcp-networkd x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 4.9 M xcp-rrdd x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 3.6 M xenopsd x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 1.4 M xenopsd-cli x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 2.0 M xenopsd-xc x86_64 26.1.19-1.2.0.romtest.1.xcpng8.3 xcp-ng-ysionneau1 5.3 M Transaction Summary ============================================================================================================================================================================================================================================================================================================================= Upgrade 22 Packages- Then you will have to manually dump your iGPU VBIOS to precisely this path:
/root/vbios.bin- for AMD modern iGPU it should be located in an ACPI table called
VFCT, you could first callacpidump -bthen use this """one liner"""
- for AMD modern iGPU it should be located in an ACPI table called
python3 -c 'import struct,sys;d=open(sys.argv[1],"rb").read();assert d[:4]==b"VFCT",d[:4];n=struct.unpack("<I",d[4:8])[0];off=struct.unpack("<I",d[0x34:0x38])[0];i=0 while off and off+28<=n: pcibus,pcidev,pcifunc,vendor,device,ssvid,ssid,rev,imagelen=struct.unpack("<IIIHHHHII",d[off:off+28]) if imagelen==0 or off+28+imagelen>n:break fn="vbios_%02d_%04x_%04x.bin"%(i,vendor,device);open(fn,"wb").write(d[off+28:off+28+imagelen]);print(fn,"bus=%d dev=%d func=%d vid=%04x did=%04x len=%d"%(pcibus,pcidev,pcifunc,vendor,device,imagelen));off+=28+imagelen;i+=1' vfct.dat- Reboot the host
- Follow the usual PCI Passthrough procedure to pass-through the iGPU PCI device to a Linux VM (a Debian 13 for instance): https://docs.xcp-ng.org/compute/#pci-passthrough
- Make sure you have the corresponding gpu firmware Debian package installed in your VM:
firmware-amd-graphicsorfirmware-intel-graphics - Start the VM
- Check in the
dmesgif the GPU is correctly detected and probed by the driver (amdgpufor AMD for instance)
What to report
Report as replies to this thread, putting text files as attached-files- If it worked or not
- the
dmesgof the Linux VM - the
xl dmesgof the host (dom0) - the output of
grep xen-pci-passthrough /var/log/xensource.log* - the
lspci -n -vvv -s SBDF(replaceSBDFwith thedomain:bus:device.function) or your GPU, both in the host (dom0) and in the VM (beware the SBDF will be different!) hexdump -C /boot/vbios.bin | head -n100on the host (dom0)
Thank you for your help!

-
Y yannsionneau referenced this topic
-
Y yannsionneau referenced this topic
-
Y yannsionneau referenced this topic
-
Y yannsionneau referenced this topic
-
Hi. I only have this after acpidump -b on a igpu from intel alder lake cpu.
ls -l | grep dat
-rw-r--r-- 1 root root 476 Oct 8 11:35 apic.dat
-rw-r--r-- 1 root root 92 Oct 8 11:35 dbg2.dat
-rw-r--r-- 1 root root 52 Oct 8 11:35 dbgp.dat
-rw-r--r-- 1 root root 480216 Oct 8 11:35 dsdt.dat
-rw-r--r-- 1 root root 276 Oct 8 11:35 facp.dat
-rw-r--r-- 1 root root 64 Oct 8 11:35 facs.dat
-rw-r--r-- 1 root root 156 Oct 8 11:35 fidt.dat
-rw-r--r-- 1 root root 68 Oct 8 11:35 fpdt.dat
-rw-r--r-- 1 root root 56 Oct 8 11:35 hpet.dat
-rw-r--r-- 1 root root 204 Oct 8 11:35 lpit.dat
-rw-r--r-- 1 root root 60 Oct 8 11:35 mcfg.dat
-rw-r--r-- 1 root root 45 Oct 8 11:35 nhlt.dat
-rw-r--r-- 1 root root 1553 Oct 8 11:35 phat.dat
-rw-r--r-- 1 root root 136 Oct 8 11:35 rmad.dat
-rw-r--r-- 1 root root 1850 Oct 8 11:35 ssdt10.dat
-rw-r--r-- 1 root root 15082 Oct 8 11:35 ssdt11.dat
-rw-r--r-- 1 root root 14810 Oct 8 11:35 ssdt12.dat
-rw-r--r-- 1 root root 324 Oct 8 11:35 ssdt13.dat
-rw-r--r-- 1 root root 916 Oct 8 11:35 ssdt14.dat
-rw-r--r-- 1 root root 419 Oct 8 11:35 ssdt15.dat
-rw-r--r-- 1 root root 427 Oct 8 11:35 ssdt16.dat
-rw-r--r-- 1 root root 7087 Oct 8 11:35 ssdt17.dat
-rw-r--r-- 1 root root 4937 Oct 8 11:35 ssdt18.dat
-rw-r--r-- 1 root root 4027 Oct 8 11:35 ssdt19.dat
-rw-r--r-- 1 root root 908 Oct 8 11:35 ssdt1.dat
-rw-r--r-- 1 root root 23819 Oct 8 11:35 ssdt2.dat
-rw-r--r-- 1 root root 10549 Oct 8 11:35 ssdt3.dat
-rw-r--r-- 1 root root 13271 Oct 8 11:35 ssdt4.dat
-rw-r--r-- 1 root root 54407 Oct 8 11:35 ssdt5.dat
-rw-r--r-- 1 root root 7962 Oct 8 11:35 ssdt6.dat
-rw-r--r-- 1 root root 10883 Oct 8 11:35 ssdt7.dat
-rw-r--r-- 1 root root 9047 Oct 8 11:35 ssdt8.dat
-rw-r--r-- 1 root root 6425 Oct 8 11:35 ssdt9.dat
-rw-r--r-- 1 root root 76 Oct 8 11:35 tpm2.dat
-rw-r--r-- 1 root root 72 Oct 8 11:35 uefi.dat
-rw-r--r-- 1 root root 40 Oct 8 11:35 wsmt.datAnd the python script throws an error :
python3 -c 'import struct,sys;d=open(sys.argv[1],"rb").read();assert d[:4]==b"VFCT",d[:4];n=struct.unpack("<I",d[4:8])[0];off=struct.unpack("<I",d[0x34:0x38])[0];i=0
while off and off+28<=n:
pcibus,pcidev,pcifunc,vendor,device,ssvid,ssid,rev,imagelen=struct.unpack("<IIIHHHHII",d[off:off+28])
if imagelen==0 or off+28+imagelen>n:break
fn="vbios_%02d_%04x_%04x.bin"%(i,vendor,device);open(fn,"wb").write(d[off+28:off+28+imagelen]);print(fn,"bus=%d dev=%d func=%d vid=%04x did=%04x len=%d"%(pcibus,pcidev,pcifunc,vendor,device,imagelen));off+=28+imagelen;i+=1' vfct.dat
Traceback (most recent call last):
File "<string>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'vfct.dat' -
-
lspci -n -vvv -s 00:02.0
00:02.0 0300: 8086:46d1 (prog-if 00 [VGA controller])
Subsystem: 8086:7270
Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin A routed to IRQ 16
Region 0: Memory at 60e7000000 (64-bit, non-prefetchable) [disabled] [size=16M]
Region 2: Memory at 4000000000 (64-bit, prefetchable) [disabled] [size=256M]
Region 4: I/O ports at 3000 [disabled] [size=64]
[virtual] Expansion ROM at 000c0000 [disabled] [size=128K]
Capabilities: [40] Vendor Specific Information: Len=0c <?>
Capabilities: [70] Express (v2) Root Complex Integrated Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0
ExtTag- RBE+
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
DevCap2: Completion Timeout: Not Supported, TimeoutDis-, LTR-, OBFF Not Supported
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
Capabilities: [ac] MSI: Enable- Count=1/1 Maskable+ 64bit-
Address: 00000000 Data: 0000
Masking: 00000000 Pending: 00000000
Capabilities: [d0] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [100 v1] Process Address Space ID (PASID)
PASIDCap: Exec- Priv-, Max PASID Width: 14
PASIDCtl: Enable- Exec- Priv-
Capabilities: [200 v1] Address Translation Service (ATS)
ATSCap: Invalidate Queue Depth: 00
ATSCtl: Enable-, Smallest Translation Unit: 00
Capabilities: [300 v1] Page Request Interface (PRI)
PRICtl: Enable- Reset-
PRISta: RF- UPRGI- Stopped+
Page Request Capacity: 00008000, Page Request Allocation: 00000000
Capabilities: [320 v1] Single Root I/O Virtualization (SR-IOV)
IOVCap: Migration-, Interrupt Message Number: 000
IOVCtl: Enable- Migration- Interrupt- MSE- ARIHierarchy-
IOVSta: Migration-
Initial VFs: 7, Total VFs: 7, Number of VFs: 0, Function Dependency Link: 00
VF offset: 1, stride: 1, Device ID: 46d1
Supported Page Size: 00000553, System Page Size: 00000001
Region 0: Memory at 00000060e0000000 (64-bit, non-prefetchable)
Region 2: Memory at 0000006000000000 (64-bit, prefetchable)
VF Migration: offset: 00000000, BIR: 0
Kernel driver in use: pcibackNow the VMs don't start at all.
vm.start
{
"id": "6783fdf9-3569-0224-fdc0-0082323305fe",
"bypassMacAddressesCheck": false,
"force": false
}
{
"code": "INTERNAL_ERROR",
"params": [
"xenopsd internal error: Cannot_add(0000:00:02.0, Device_common.QMP_Error(5, "{\"error\":{\"class\":\"GenericError\",\"desc\":\"failed to find romfile \\\"/root/vbios.bin\\\"\",\"data\":{}},\"id\":\"qmp-000015-5\"}"))"
],
"call": {
"duration": 4031,
"method": "VM.start",
"params": [
"* session id *",
"OpaqueRef:2877507a-7ad9-f1e6-2b9c-e5690cb21e76",
false,
false
]
},
"message": "INTERNAL_ERROR(xenopsd internal error: Cannot_add(0000:00:02.0, Device_common.QMP_Error(5, "{\"error\":{\"class\":\"GenericError\",\"desc\":\"failed to find romfile \\\"/root/vbios.bin\\\"\",\"data\":{}},\"id\":\"qmp-000015-5\"}")))",
"name": "XapiError",
"stack": "XapiError: INTERNAL_ERROR(xenopsd internal error: Cannot_add(0000:00:02.0, Device_common.QMP_Error(5, "{\"error\":{\"class\":\"GenericError\",\"desc\":\"failed to find romfile \\\"/root/vbios.bin\\\"\",\"data\":{}},\"id\":\"qmp-000015-5\"}")))
at XapiError.wrap (file:///opt/xo/xo-builds/xen-orchestra-202610080923/packages/xen-api/_XapiError.mjs:16:12)
at file:///opt/xo/xo-builds/xen-orchestra-202610080923/packages/xen-api/transports/json-rpc.mjs:38:21
at runNextTicks (node:internal/process/task_queues:65:5)
at processImmediate (node:internal/timers:541:9)"
} -
@ovicz in your case it seems the vbios is in the ROM BAR.
You can dump the vbios by doing something likecd /sys/bus/pci/devices/0000:00:02.0/ echo 1 > rom cat rom > /root/vbios.bin echo 0 > rom -
Another possibility for you would be to
yum downgradeqemu and the xapi packages, everything except edk2 and try again. -
@yannsionneau cd /sys/bus/pci/devices/0000:00:02.0/
[11:55 xcp-ng-akz 0000:00:02.0]# echo 1 > rom
[11:55 xcp-ng-akz 0000:00:02.0]# cat rom > /root/vbios.bin
cat: rom: Input/output error
[11:55 xcp-ng-akz 0000:00:02.0]# echo 0 > rom -
@yannsionneau Reverted to stable and I upgraded only that package from your repo. VMs start now. At what should i look for now ?
-
@ovicz with the new edk2 package it should help your VM access the vbios in the rom bar.
Does the VM see the gpu?
Can you share the VM dmesg as attached file?
Also, are you trying to passthrough a sriov virtual function? or the entire physical gpu?
Thanks -
Yes it does see it.
dmesg.txt
Passthrough was working and without that file from your repo. -
@ovicz It seems your gpu works even without vbios since in your dmesg I can see
[ 7.424250] i915 0000:00:08.0: Invalid PCI ROM header signature: expecting 0xaa55, got 0x0000 [ 7.424259] i915 0000:00:08.0: [drm] Failed to find VBIOS tables (VBT)So you're saying that anyway your setup was working even without all those new packages?
Thanks for testing anyway! -
@yannsionneau Yes it works with the stock packages.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login