Learn how to resolve host freezing issues caused by GPU passthrough in Windows 10/11 virtual machines using libvirt and KVM on Linux, with a simple hook script solution.
Problem:
- After successfully passing a GPU to guest OS (I have only tested with Windows 10/11 guests), the system works fine until the guest is shut down.
- As soon as the guest powers down (whether by using shutdown inside the guest or using Virtual Machine Manager’s force stop), the host freezes, leaving a hard reboot as the only option.
Solution:
- Create a file named
daemon (with no extension) in /etc/libvirt/hooks/ containing the following code:
#!/bin/bash
if [[ "$2" == "start" ]]
then
echo "Trying to reset gpus"
echo > /sys/bus/pci/devices/0000:03:00.0/reset_method
echo > /sys/bus/pci/devices/0000:04:00.0/reset_method
echo "Finished reset"
fi
- The location and name of the file ensure it runs when
libvirt starts.
Assumption:
- You have already isolated your GPU and passthrough works without hiccups.
- If you are looking for how to isolate a GPU, refer to: Arch Linux PCI Passthrough via OVMF
- This might be overwhelming for someone new to Linux, but it’s worth trying.
- I may write a future tutorial on how I did it, in a simple and concise form.
What does it do?
- This script resets the GPU bindings when
libvirt starts.
- I’m not deeply familiar with
libvirt and KVM, so I can’t explain why this step is necessary. However, after trying many approaches, this solution has been stable for over six months.
How I found the solution:
- After trying system updates and OS changes (I even switched from Ubuntu to OpenSUSE thinking the latest drivers might help), I spent over 50 hours googling the solution.
- Here are some of the sources that gave me hints:
- While one of these worked temporarily, the final solution I found was by manually running GPU reset commands at different times and noting the correct sequence.
- Once I confirmed it needs to run before I start
libvirt (which is started when you launch Virtual Machine Manager), I tested this script.
- I implemented it more than 6 months ago and have not needed to change it since. This should fix the issue for most people facing this problem.
My System:
- OpenSUSE Tumbleweed
- MSI PRO Z690-A WIFI DDR5
- Intel i5-13600K + Arc A770 16 GB
- I have isolated the Arc A770 and use the iGPU for all other host purposes.
- I’m running Windows 10 as a guest OS with the GPU passed through.
- Passing a GPU to Ubuntu guests also works, so other distros should work too.