Hardware Builds #proxmox#gpu-passthrough#vfio

GPU Passthrough for Gaming VMs with Proxmox and QEMU

Step-by-step GPU passthrough on Proxmox: IOMMU, VFIO binding, Windows VM setup, Looking Glass display, and performance vs bare metal gaming.

7 min read

GPU passthrough lets you dedicate a physical graphics card to a virtual machine, giving a Windows gaming VM near-bare-metal GPU performance while the rest of your system runs Linux or Proxmox. It’s one of the most rewarding — and technically demanding — projects in the home lab world. Here’s how to do it properly.

Prerequisites

Before starting, verify your hardware:

  • CPU with IOMMU support: AMD (all Ryzen/EPYC) or Intel (VT-d capable Core CPUs)
  • Motherboard with IOMMU enabled in BIOS: Look for AMD-Vi or Intel VT-d in BIOS settings
  • Two GPUs: One for the host (or use CPU integrated graphics), one for passthrough — or use the single-GPU passthrough method (more complex, not covered here)
  • Proxmox VE 8.x installed and updated

Single-GPU setups are possible but require additional scripting to detach and reattach the GPU at VM start/stop. Dual-GPU is strongly recommended.

Step 1: Enable IOMMU in BIOS and Kernel

BIOS Settings

  • AMD: Enable AMD-Vi or IOMMU (usually under CPU or Advanced settings)
  • Intel: Enable VT-d (Intel Virtualization Technology for Directed I/O)

Also enable Above 4G Decoding and Resizable BAR if available — some GPUs require these for correct passthrough behavior.

Kernel Parameters

Edit the GRUB configuration on your Proxmox host:

nano /etc/default/grub

Find the line with GRUB_CMDLINE_LINUX_DEFAULT and modify it:

For AMD:

GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"

For Intel:

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

The iommu=pt (passthrough mode) flag improves performance for devices that are not passed through by skipping unnecessary IOMMU translation.

Apply the changes:

update-grub
reboot

After reboot, verify IOMMU is active:

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

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

Step 2: Check IOMMU Groups

IOMMU groups determine which devices can be passed through together. Ideally, your GPU and its audio device are in their own group with no other devices.

#!/bin/bash
for d in /sys/kernel/iommu_groups/*/devices/*; do
    n=${d#*/iommu_groups/*}; n=${n%%/*}
    printf 'IOMMU Group %s ' "$n"
    lspci -nns "${d##*/}"
done | sort -V

Save this as a script and run it. Look for your GPU’s lines — they should show something like:

IOMMU Group 12 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [RTX 3060] [10de:2487]
IOMMU Group 12 01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio [10de:228b]

If other devices (like a PCIe bridge) share that group, you may need to pass through those devices too, or enable ACS override (a kernel patch available in some Proxmox builds) to split groups artificially. AMD Ryzen systems generally have better IOMMU grouping than Intel consumer platforms.

Step 3: Load VFIO Modules

VFIO (Virtual Function I/O) is the kernel framework that makes passthrough work. Add the required modules:

echo "vfio" >> /etc/modules
echo "vfio_iommu_type1" >> /etc/modules
echo "vfio_pci" >> /etc/modules
echo "vfio_virqfd" >> /etc/modules

Then update initramfs:

update-initramfs -u -k all

Step 4: Bind the GPU to VFIO-PCI

Find your GPU’s PCI IDs:

lspci -nn | grep -i nvidia
# Example output:
# 01:00.0 VGA ... [10de:2487]
# 01:00.1 Audio ... [10de:228b]

Create a VFIO options file with your GPU’s IDs:

echo "options vfio-pci ids=10de:2487,10de:228b" > /etc/modprobe.d/vfio.conf

If your GPU uses the nouveau or nvidia driver by default, blacklist it so VFIO claims the device first:

echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf
echo "blacklist nvidiafb" >> /etc/modprobe.d/blacklist.conf

Update initramfs again and reboot:

update-initramfs -u -k all
reboot

Verify VFIO claimed the GPU:

lspci -nnk -d 10de:2487
# Should show: Kernel driver in use: vfio-pci

Step 5: Create the Windows VM in Proxmox

In the Proxmox web UI, create a new VM with these settings:

General:

  • Machine: q35
  • BIOS: OVMF (UEFI) — required for GPU passthrough with modern NVIDIA cards

CPU:

  • Type: host
  • Enable NUMA topology if your host has multiple NUMA nodes

Memory:

  • Enable Ballooning: No for GPU passthrough (fixed allocation)
  • Set 16–32GB for a gaming VM

Disk:

  • VirtIO SCSI controller
  • At least 100GB for Windows + games

Network:

  • VirtIO network adapter for best performance

After creating the VM, add the GPU via Hardware > Add > PCI Device:

  • Select your GPU (01:00.0)
  • Enable All Functions (captures the audio device automatically)
  • Enable ROM-Bar
  • Enable PCI-Express (x16 mode)
  • Optionally set Primary GPU if this is the only GPU being used for display in the VM

Step 6: VirtIO Drivers

Windows doesn’t include VirtIO drivers by default. Download the VirtIO Windows Drivers ISO from Fedora’s official repository and attach it as a second CD drive in Proxmox.

During Windows installation, when prompted for a driver at the storage screen, browse to the VirtIO ISO and install the vioscsi driver. After installation completes, install all drivers from the VirtIO ISO in Device Manager.

Key drivers:

  • vioscsi — storage controller
  • NetKVM — network adapter
  • Balloon — memory management
  • viogpudo — display (for non-passthrough displays)

Step 7: Looking Glass for Display Output

Looking Glass solves a core problem: the GPU is connected to the VM, but the physical monitor is plugged into it. Looking Glass uses shared memory to stream the GPU’s framebuffer to a client running on the Proxmox host’s display (or another machine).

Setup overview:

  1. Add a shared memory device (IVSHMEM) to the VM configuration in /etc/pve/qemu-server/VMID.conf:
    ivshmem: size=128,name=looking-glass
  2. Install the Looking Glass host application inside the Windows VM (B7 or later release)
  3. Run the Looking Glass client on the Linux host to display the VM’s output

Looking Glass supports up to 4K at 60fps with sub-5ms latency on fast hardware — nearly indistinguishable from native for most games.

Step 8: Audio Passthrough

Options for VM audio:

  • Pass through the GPU HDMI/DP audio (included when you pass through all GPU functions) — routes audio through the monitor speakers or AVR connected to the GPU
  • USB audio device passthrough — attach a USB DAC/headphone amp to the VM via USB passthrough
  • Virtio-sound (newer Proxmox/QEMU feature) — software audio bridge with acceptable latency for games

For the cleanest experience, use a dedicated USB audio device for the gaming VM.

Performance Expectations vs Bare Metal

With proper configuration, GPU passthrough achieves:

  • Gaming FPS: 95–99% of bare metal performance in most titles
  • Micro-stutter: Generally absent with iommu=pt and proper CPU pinning
  • VRAM access: Full native VRAM bandwidth (no virtualization overhead)

Where you do pay a penalty:

  • CPU scheduling latency: Pin vCPUs to physical cores using taskset or Proxmox’s CPU affinity settings
  • DMA overhead: Minimal with VFIO, negligible in practice
  • Anti-cheat software: Kernel-level anti-cheat (Vanguard, Easy Anti-Cheat) may detect virtualization via CPUID flags. Masking CPUID in Proxmox (args: -cpu host,kvm=off,hv_vendor_id=GenuineIntel) resolves this for most titles, but some anti-cheat updates actively block VMs
ComponentRecommendation
Host CPUAMD Ryzen 7 7700 (strong IOMMU groups)
Host GPU (Linux)Intel Arc A310 (low-power, good Linux drivers)
Guest GPUNVIDIA RTX 5070 or AMD RX 7800 XT
RAM64GB DDR5 (32GB for host, 32GB for VM)
StorageSeparate NVMe per OS (host + guest)

GPU passthrough is complex to configure but remarkably stable once running. The payoff — a full Linux desktop with a dedicated gaming VM that rivals a bare-metal Windows install — makes it one of the most satisfying home lab achievements.

#iommu #gaming-vm #vfio #gpu-passthrough #proxmox