Summary of "I Almost Lost My Virtual Machines..."

Overview

This is a technical how‑to for single‑GPU passthrough on an Arch/Manjaro host so you can run Windows inside QEMU/KVM and give the guest exclusive access to a single physical GPU (author used an RTX 3090). The guide covers:

The tutorial is practical and step‑by‑step with runnable scripts and examples, but repeatedly warns that setups differ and you’ll likely need to “taste and adjust” per your hardware.

Warning: every system is different — IOMMU groups, drivers, display manager names, and PCI addresses vary. Test carefully and adapt scripts to your hardware. ROM dumping/patching can be risky; back up originals.

Key concepts and benefits

Prerequisites

Concrete step summary (ordered)

  1. Enable IOMMU in kernel boot params

    • Edit /etc/default/grub and add intel_iommu=on (or amd_iommu=on for AMD).
    • Rebuild grub: sudo grub-mkconfig -o /boot/grub/grub.cfg and reboot.
  2. Verify IOMMU grouping

    • Use dmesg | grep -i iommu or the grouping script from the Arch wiki to confirm IOMMU is enabled and to list PCI IDs/groups.
    • Save the GPU PCI IDs (author saved them to a text file for later use).
  3. Install virtualization packages

    • Install QEMU/libvirt/OVMF/virt‑manager and start/enable libvirt services; enable the default libvirt network.
  4. VBIOS / ROM handling

    • Options:
      • Download the exact VBIOS from a repository such as TechPowerUp.
      • Dump the ROM from your GPU with appropriate tools (risky).
    • If required, patch the ROM (hex editor like bless). Keep the original dump backed up and save the patched ROM for attaching to the VM.
  5. Create the VM in virt‑manager

    • Use local install media (Windows ISO). Allocate memory/CPU/disk.
    • Use OVMF (UEFI) firmware (ovmf_code.fd) — UEFI is required for many single‑GPU setups.
    • Configure CPU topology to mirror the host cores/threads (recommended).
    • Ensure CD‑ROM boot is enabled for the installer.
  6. Create libvirt hooks to automate GPU switching

    • Directory structure example:
      • /etc/libvirt/hooks/qemu.d/<VM-name>/prepare/start.sh
      • /etc/libvirt/hooks/qemu.d/<VM-name>/release/revert.sh
    • prepare/start.sh should:
      • stop the display manager (e.g., systemctl stop sddm.service), unbind VT consoles and EFI framebuffer, remove host GPU modules, and bind the GPU to vfio-pci.
    • release/revert.sh should:
      • unload vfio, rebind the GPU to host drivers, restore VT consoles/EFI framebuffer, and restart the display manager.
    • Scripts should source a small config file such as /etc/libvirt/hooks/kvm.conf that contains PCI IDs as variables (e.g., verse_gpu_video=pci_0000_01_00_0 using underscores).
    • Make the scripts executable: sudo chmod +x /etc/libvirt/hooks/qemu.d/...
  7. Attach the GPU and ROM to the VM

    • In virt‑manager, add “PCI Host Device” entries for the GPU functions (GPU display, GPU audio, and any USB/other functions).
    • Edit the VM XML and add a ROM line under the device so the VM uses the patched ROM, for example:
      • <rom file='/home/<user>/patch.rom'/>
  8. Spoof vendor_id / hide KVM flags to bypass NVIDIA Error 43

    • Edit VM XML (features) to add a vendor_id element under <features>/<hyperv> or set vendor_id state='on' value='SOME_STRING'.
    • Optionally hide KVM CPU flags if needed.
  9. Test

    • Start the VM and watch the hooks unload host drivers and bind the GPU to VFIO. Windows should detect the GPU in Device Manager.
    • On VM shutdown, the release script should return the GPU to the host cleanly.

Libvirt hooks — implementation notes

VBIOS / ROM handling

NVIDIA Error 43 workarounds

Troubleshooting & notes

Commands & files mentioned (examples)

Resources / further reading

Speaker / sponsor

Category ?

Technology


Share this summary


Is the summary off?

If you think the summary is inaccurate, you can reprocess it with the latest model.

Video