Hi,
First post here.. Owner of a 9070XT (using APU as boot default) and trying to virtualize away my only windows baremetal machine.
Mostly don’t game much anymore but still tied to MS because I need GSPro golf sim and some custom audio calibration tools on windows..
Got my win10 image setup on my fedora 44 workstation and passthrough of 9070XT working fine after experimentation (wasted my time on Gemini’s bs guesses instead of trusting my experience!). Still getting AMD reset bug.
Tried pretty much every technique under the sun to workaround it (I don’t like to quit).
The problem is you can poke at setpci poke anything and echo “bind” to /sys yourself crazy but nothing will reset the card after windows pooped on it.
Installed fedora testing kernel 7.2–rc3 via COPR and noticed that amdgpu is MUCH better at dealing with errors and failing gracefully now.. (ip discovery failure post windows guest shutdown is more descriptive too)
I decided to compile the bleeding edge amdgpu/kernel yesterday (with latest linux-firmware) and even with multiple combination of AMDGPU kernel options still no pseudo FLR reset workaround. (if it’s even possible)
So until devs find a way to artificially FLR this thing this is good enough for me:
The way I settled on (for now), was to leave amdgpu binded on bootup (to init GPU properly) and let libvirt auto manage it. and then I used this hook script to do a short system suspend to ram by RTC (no need to physically be there) and then the GPU comes fully resetted and I can start vm again. rebooting works fine too now.
#!/bin/bash
# /etc/libvirt/hooks/qemu
GUEST_NAME="win10"
GPU_GFX="0000:03:00.0"
GPU_AUD="0000:03:00.1"
# Phase 1: Lockout
if [ "$1" = "$GUEST_NAME" ] && [ "$2" = "started" ] && [ "$3" = "begin" ]; then
echo "dummy" > /sys/bus/pci/devices/${GPU_GFX}/driver_override
echo "dummy" > /sys/bus/pci/devices/${GPU_AUD}/driver_override
exit 0
fi
# Phase 2: Hardware S3 Reset Transition
if [ "$1" = "$GUEST_NAME" ] && [ "$2" = "stopped" ] && [ "$3" = "end" ]; then
# 1. Force the sleep cycle to wipe the RDNA4 firmware state
rtcwake -m mem -s 5
sleep 2.0
# 2. Release the overrides so the kernel's auto-resume can natively map them
echo "" > /sys/bus/pci/devices/${GPU_GFX}/driver_override
echo "" > /sys/bus/pci/devices/${GPU_AUD}/driver_override
# 3. Explicitly tell libvirt that the script finished successfully
exit 0
fi
Not claiming it’s a novel method in any way of course but just documenting for others as most examples were for single GPU and proxmox..
here’s my current kernel cmdline for reference:
BOOT_IMAGE=(hd0,gpt2)/vmlinuz-7.1.0+ root=UUID=a5cc57bf-f256-475e-a7df-8b973d901c2c ro rootflags=subvol=root amd_iommu=on iommu=pt pcie_aspm=off pcie_port_pm=off amdgpu.gpu_recovery=1
ps: i’ll eventually clean that up though as most of those didn’t make a difference while testing. (you do need amd_iommu=on iommu=pt)
win10.xml snippet:
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
</source>
<alias name='hostdev1'/>
<rom file='/var/lib/libvirt/roms/Sapphire.RX9070XT.16384.241204.rom'/>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0' multifunction='on'/>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x09' slot='0x00' function='0x0'/>
</source>
<alias name='hostdev2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</hostdev>
Might not need to pass ROM file but haven’t had a chance to clean up. might add an update later.
Cheers,