$linuxjunkies
>

GPU Passthrough for a Gaming VM

Pass a GPU directly to a KVM/QEMU Windows VM using IOMMU, vfio-pci, and Looking Glass — with honest notes on anti-cheat compatibility.

AdvancedUbuntuDebianFedoraArch14 min readUpdated June 7, 2026

Before you start

  • CPU and motherboard with Intel VT-d or AMD-Vi support, enabled in UEFI
  • A dedicated GPU to pass through (a second card for the host is strongly recommended)
  • Linux kernel 6.1 or newer (for reliable vfio-pci and IOMMU support)
  • Root/sudo access and comfort editing bootloader config and libvirt XML

GPU passthrough lets you hand a physical GPU directly to a KVM virtual machine, giving a Windows gaming guest near-native graphics performance while your Linux host keeps running on the CPU's integrated graphics or a second discrete card. The stack involves IOMMU groups, the vfio-pci kernel driver, QEMU/libvirt, and optionally Looking Glass for a zero-latency shared-memory display. It is genuinely complex — expect an afternoon the first time, and know that some anti-cheat software (Valorant's Vanguard, EA's EAC in kernel mode) will refuse to run in a VM regardless of how well you hide the hypervisor.

Prerequisites and Hardware Checks

You need a CPU and motherboard that support IOMMU, a GPU to dedicate to the VM (ideally a second card; passing your only GPU is possible but much harder), and a way to display the guest — either a second monitor or Looking Glass. Check BIOS/UEFI for Intel VT-d or AMD-Vi and enable it before continuing.

  • Intel: enable VT-d in UEFI
  • AMD: enable IOMMU (sometimes labeled AMD-Vi or SVM) in UEFI
  • Secure Boot: disable it for now — you can re-enable it later with signed modules if needed
  • At least 16 GB RAM recommended; the guest should get 8 GB or more

Step 1 — Enable IOMMU in the Kernel

Add the correct kernel parameter to your bootloader.

GRUB (Debian/Ubuntu, Fedora, Rocky)

Edit /etc/default/grub and append to GRUB_CMDLINE_LINUX_DEFAULT:

# Intel
intel_iommu=on iommu=pt

# AMD
amd_iommu=on iommu=pt

iommu=pt (passthrough mode) reduces overhead for devices that stay on the host.

# Debian/Ubuntu
sudo update-grub

# Fedora / Rocky
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

systemd-boot (Arch, some Fedora installs)

sudo nano /boot/loader/entries/arch.conf
# Append intel_iommu=on iommu=pt (or amd_iommu=on iommu=pt) to the options line
sudo bootctl update

Reboot, then verify IOMMU is active:

dmesg | grep -e IOMMU -e DMAR | head -20

You should see lines like DMAR: IOMMU enabled or AMD-Vi: AMD IOMMUv2 loaded.

Step 2 — Identify Your GPU's IOMMU Group

Each PCI device belongs to an IOMMU group. You must pass through every device in the group that contains your GPU — passing only the GPU while leaving the group's audio device on the host will fail. Use this script:

for d in /sys/kernel/iommu_groups/*/devices/*; do
  n=${d#*/iommu_groups/}; n=${n%%/*}
  printf 'Group %s: ' "$n"
  lspci -nns "${d##*/}"
done

Find your target GPU in the output. Note its PCI IDs (e.g., 10de:2204 for the GPU and 10de:1aef for its HDMI audio). If the group contains unrelated devices like a PCIe root port, you may need an ACS patch kernel (available in the AUR as linux-zen or via third-party repos) — that is outside this guide's scope.

Step 3 — Bind the GPU to vfio-pci

The GPU must be claimed by vfio-pci before the host driver loads at boot.

Load vfio modules early

sudo nano /etc/modprobe.d/vfio.conf

Add (replace IDs with your actual PCI IDs from step 2):

options vfio-pci ids=10de:2204,10de:1aef
softdep nouveau pre: vfio-pci
softdep nvidia pre: vfio-pci
softdep amdgpu pre: vfio-pci
softdep radeon pre: vfio-pci

The softdep lines make vfio-pci load before any GPU driver, so the GPU is claimed first.

Rebuild initramfs

# Debian/Ubuntu
sudo update-initramfs -u -k all

# Fedora / Rocky
sudo dracut --force

# Arch
sudo mkinitcpio -P

Reboot and verify the GPU is bound to vfio-pci:

lspci -nnk -d 10de:2204

The Kernel driver in use: line must read vfio-pci, not nvidia or amdgpu.

Step 4 — Install QEMU, libvirt, and Utilities

# Debian/Ubuntu
sudo apt install qemu-kvm libvirt-daemon-system virtinst ovmf virt-manager

# Fedora
sudo dnf install @virtualization edk2-ovmf virt-manager

# Arch
sudo pacman -S qemu-full libvirt virt-manager ovmf dnsmasq
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm "$USER"

Log out and back in so group membership takes effect.

Step 5 — Create the VM and Attach the GPU

Use virt-manager to create a Windows 11 VM with these settings before first boot:

  • Firmware: UEFI (select the OVMF/UEFI option — required for modern Windows and for hiding the hypervisor)
  • Chipset: Q35
  • CPU: match host CPU topology; enable host-passthrough CPU model
  • Remove the emulated QXL/VGA video device after adding the passed-through GPU
  • Add PCI Host Device: select your GPU and its companion audio device

Add the virtio-win ISO as a second CD-ROM so Windows can find its network and storage drivers during install.

Hiding the VM from drivers and anti-cheat

Edit the VM's XML (virsh edit vmname) and add a Hyper-V enlightenments block and a KVM feature mask. This convinces Windows and some anti-cheat systems they are on real hardware — though it is not foolproof:

virsh edit windows-gaming

Inside <features>:

<hyperv mode="custom">
  <relaxed state="on"/>
  <vapic state="on"/>
  <spinlocks state="on" retries="8191"/>
  <vendor_id state="on" value="GenuineIntel"/>
</hyperv>
<kvm>
  <hidden state="on"/>
</kvm>
<ioapic driver="kvm"/>

Looking Glass streams the guest framebuffer to a client window on the host over shared memory — no second monitor needed, with latency in the low milliseconds.

# Arch
sudo pacman -S looking-glass

# Fedora
sudo dnf install looking-glass looking-glass-host-module

# Debian/Ubuntu — build from source; see https://looking-glass.io/docs/stable/build/

Add a shared memory device to the VM XML:

<shmem name="looking-glass">
  <model type="ivshmem-plain"/>
  <size unit="M">128</size>
</shmem>

128 MB covers up to 1440p; use 256 MB for 4K. Install the Looking Glass host application inside Windows, then launch the client on Linux:

looking-glass-client -F

Step 7 — Verify GPU is Working in the Guest

Inside the Windows VM, open Device Manager — the GPU should appear without a warning triangle. Install the vendor driver (NVIDIA/AMD) normally. Run dxdiag and confirm DirectX sees the GPU with correct VRAM. Run a quick benchmark like 3DMark Time Spy to confirm near-native performance; expect 90–98% of bare-metal scores.

Anti-Cheat Caveats

This is the hard truth: kernel-level anti-cheat is an arms race.

  • Valorant (Vanguard): detects KVM via CPUID leaves and the hypervisor bit. As of 2024 it will not run in a VM regardless of kvm hidden settings. Riot has explicitly said this is intentional.
  • Easy Anti-Cheat / BattlEye: vary by game. Many titles work fine; some (Hunt: Showdown at certain patch levels, for example) detect the VM. Check game-specific forums.
  • FACEIT: generally blocks VMs.
  • GPU passthrough does not bypass these checks by itself — the hypervisor is still detectable via timing attacks, CPUID, and ACPI table signatures.

Troubleshooting

  • GPU driver loads on host instead of vfio-pci: your initramfs does not include vfio modules early enough. On Arch, add vfio_pci vfio vfio_iommu_type1 to the MODULES array in /etc/mkinitcpio.conf before mkinitcpio -P.
  • IOMMU groups contain extra PCIe root ports: you need ACS override. This carries a security trade-off (devices in the enlarged group can DMA into each other). The linux-zen kernel on Arch includes the patch; Fedora users can use a COPR kernel.
  • VM boots but no GPU output: check that the emulated video device was removed from the XML. QEMU will prefer the emulated device if it is present.
  • Looking Glass shows a black screen: the host binary must be running inside Windows, and the shared memory permissions must allow your user (/dev/shm/looking-glass should be owned by your UID).
  • NVIDIA Code 43 error: you need the vendor_id and kvm hidden XML entries from Step 5. On recent drivers (500+) this is largely resolved, but older guest drivers still trigger it.
tested on:Ubuntu 24.04Fedora 40Arch rolling-2024Debian 12

Frequently asked questions

Can I pass through my only GPU if my CPU has no integrated graphics?
Yes, but it requires either a dummy HDMI plug, a second cheap GPU for the host, or running the host headlessly via SSH. The GPU must be unbound from the host driver before the VM starts, so you lose the host display entirely once it is passed through.
Will Valorant run in a GPU passthrough VM?
No. Riot's Vanguard anti-cheat explicitly detects KVM hypervisors through CPUID and refuses to start as of 2024, and Riot has confirmed this is a deliberate policy.
Does GPU passthrough work with a single NVIDIA card and no second GPU?
It works but requires a workaround called VFIO-Unlock or the vendor reset patch, and NVIDIA's driver may not release the GPU cleanly when the VM shuts down, requiring a host reboot. A second GPU for the host avoids all of this.
What is the performance penalty compared to bare metal?
GPU rendering performance is typically within 2–5% of bare metal. CPU-bound games may see slightly more overhead depending on how many cores you allocate and whether CPU pinning is configured; I/O latency can be improved by using virtio-scsi or NVMe passthrough instead of emulated SATA.
Do I need Looking Glass, or can I plug a second monitor into the passed-through GPU?
A second physical monitor is the simplest option and has zero software overhead — the guest outputs directly to the display. Looking Glass is useful when you only have one monitor or want to run the guest in a window on the host desktop.

Related guides