Fix Host Freezing After GPU Passthrough in Windows 10/11 Guests with libvirt & KVM on Linux

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.
Built with Hugo
Theme Stack designed by Jimmy