[ Zum Inhalt springen ]
TUTORIALS / VIRTUALIZATION

GPU PASSTHROUGH VM

DIFFICULTY: EXTREME UPDATED:
GPU Passthrough VM

INTRODUCTION

Running a virtual machine usually means sacrificing graphics performance. GPU Passthrough (VFIO) solves this by giving the VM direct access to a physical GPU, allowing for near-native performance. This is the holy grail for Linux users who need to run Windows games or Adobe software without dual-booting.

With proper configuration, you can achieve 95-99% of bare metal performance, run most games (some anti-cheats such as Vanguard or FACEIT block VMs), and maintain your secure Linux host environment.

VFIO GPU Passthrough Architecture

Linux Host
QEMU/KVM
VFIO Driver
→
IOMMU
DMA Remapping
Isolation
→
Windows VM
GPU Driver
Direct Access
Host GPU remains available for Linux, passed GPU has near-native performance in VM

PREREQUISITES

  • CPU with VT-d (Intel) or AMD-Vi (AMD) support - Check your processor specs
  • Motherboard with IOMMU support - Usually any modern board supports this
  • Two GPUs OR single-GPU passthrough - Dual GPU is easier for beginners
  • Linux Host - Arch Linux recommended (best documentation), Ubuntu/Fedora also work
  • Minimum 16GB RAM - You'll need to allocate 8GB+ to the VM

⚠️ WARNING

Incorrect BIOS modifications can brick your motherboard. Always have a backup plan and read the full guide before proceeding.

STEP-BY-STEP INSTRUCTIONS

Step 1: Enable IOMMU in BIOS/UEFI

Reboot into your BIOS (usually DEL or F2 during boot). Navigate to the Advanced or CPU Configuration section.

Look for and enable:

  • Intel VT-d (Intel CPUs) or AMD-Vi / IOMMU (AMD CPUs)
  • Intel Virtualization Technology / SVM Mode
  • Disable CSM/Legacy Boot (use UEFI only)

IOMMU Groups Example

IOMMU Group 1 (Isolated GPU) ✓
01:00.0 VGA compatible controller: NVIDIA GPU
01:00.1 Audio device: NVIDIA GPU Audio
IOMMU Group 2 (Mixed devices - Problematic ✗)
02:00.0 USB Controller
02:00.1 GPU (shared with USB!)
Goal: GPU should be alone in its IOMMU group for proper passthrough

Step 2: Enable IOMMU in Kernel Parameters

Edit your bootloader config to enable IOMMU at the kernel level. For GRUB, edit /etc/default/grub:

# For Intel CPUs:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

# For AMD CPUs (IOMMU is on by default once enabled in BIOS; "amd_iommu=on" is not a valid option):
GRUB_CMDLINE_LINUX_DEFAULT="quiet iommu=pt"

Then update GRUB and reboot:

sudo grub-mkconfig -o /boot/grub/grub.cfg # Arch (Ubuntu: sudo update-grub)
sudo reboot

Step 3: Verify IOMMU Groups

After reboot, check your IOMMU groups to ensure devices are properly isolated:

#!/bin/bash
shopt -s nullglob
for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
    echo "IOMMU Group ${g##*/}:"
    for d in $g/devices/*; do
        echo -e "\t$(lspci -nns ${d##*/})"
    done;
done;

Your GPU and its audio controller should ideally be in their own IOMMU group, or at minimum in a group with no critical devices.

Step 4: Isolate the GPU with VFIO

Find your GPU's PCI IDs using lspci -nnk. Look for your GPU and note the IDs in brackets (e.g., [10de:1b80]).

Create /etc/modprobe.d/vfio.conf:

# Replace with your GPU's vendor:device IDs
options vfio-pci ids=10de:1b80,10de:10f0

# Load vfio-pci before graphics drivers
softdep nvidia pre: vfio-pci
softdep amdgpu pre: vfio-pci

Update initramfs and reboot:

sudo mkinitcpio -P # Arch Linux
sudo update-initramfs -u # Ubuntu/Debian

Step 5: Install Virtualization Software

# Arch Linux
sudo pacman -S qemu-full libvirt virt-manager edk2-ovmf

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

Enable and start libvirt:

sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt $USER

Step 6: Create the VM in Virt-Manager

  1. Open Virt-Manager and click "Create a new virtual machine"
  2. Choose "Local install media" and select your Windows ISO
  3. Allocate at least 8GB RAM and 4 CPU cores
  4. Important: Select "Customize configuration before install"
  5. In Overview, set Firmware to "UEFI x86_64: ...OVMF_CODE..." (path varies, e.g. /usr/share/OVMF/OVMF_CODE_4M.fd on Ubuntu, /usr/share/edk2/x64/OVMF_CODE.4m.fd on Arch)
  6. In CPUs, check "Copy host CPU configuration"
  7. Remove the default video adapter (Spice/QXL)
  8. Click "Add Hardware" → "PCI Host Device" → Select your GPU
  9. Add Hardware again and select the GPU's audio controller

Step 7: Optional - Looking Glass Setup

For low-latency frame relay from guest to host without a second monitor:

# Install Looking Glass
yay -S looking-glass # Arch AUR

# Add IVSHMEM device to VM XML
virsh edit [VM_NAME]

# Add before \u003c/devices\u003e:
\u003cshmem name='looking-glass'\u003e
  \u003cmodel type='ivshmem-plain'/\u003e
  \u003csize unit='M'\u003e32\u003c/size\u003e
\u003c/shmem\u003e

CONCLUSION & TROUBLESHOOTING

If successful, you now have a Windows VM that performs within 95-99% of bare metal. You can play many games and use CUDA acceleration — but some anti-cheats (e.g. Vanguard, FACEIT) block VMs.

Common Issues:

  • Code 43 Error: Use a current NVIDIA driver (R465+ officially allows GeForce passthrough); only very old drivers need vendor_id to hide the VM
  • Black Screen: Try different OVMF firmware versions or add video=efifb:off to kernel params
  • VM Won't Start: Check IOMMU groups and ensure GPU isn't in use by host

FAQ / TROUBLESHOOTING

⚠️ Detailed answers to the most common issues

❌ Code 43 error in Windows Device Manager for the passed GPU

NVIDIA drivers before R465 (2021) refused to run GeForce cards in a VM; current drivers officially support GeForce passthrough. Today Code 43 usually means the GPU is still bound to the host, a bad/missing vBIOS ROM, or (AMD) the GPU reset bug. For very old drivers the classic fix still applies: add <vendor_id state="on" value="1234567890ab"/> inside <hyperv> and <kvm><hidden state="on"/></kvm> in the VM's <features> section.

❌ My GPU is grouped with the USB controller in one IOMMU group

Common on older AMD boards. You need an ACS override patch in your kernel, or use the vfio-pci.ids= trick to bind the whole group at once. The proper long-term fix is a newer motherboard with better IOMMU segmentation.

❌ Audio doesn't work over HDMI/DP from the passed GPU

You need to pass through both the GPU (VGA controller) and its audio function (usually 01:00.1). Then in Windows, set the HDMI audio as the default playback device in Sound Settings.

❌ Performance is only 80% of bare metal, not 95-99%

Check the following:

  • Enable Hyper-V enlightenments (<hyperv> block in VM XML: relaxed, vapic, spinlocks)
  • Use cpu host-passthrough in VM XML (not host-model)
  • Pin CPU cores to the VM with <vcpupin> taskset
  • Use hugepages: echo 4096 > /proc/sys/vm/nr_hugepages (4096 × 2 MiB = 8 GiB VM RAM) plus <memoryBacking><hugepages/> in the XML
  • Set the disk driver to virtio (single-driver) and use writeback cache
❌ Can I do single-GPU passthrough (no second GPU)?

Yes, but more complex. The host must release the GPU before VM start: libvirt hook scripts stop the display manager and unbind the GPU from the host driver, then return it after shutdown (no static vfio-pci.ids binding — otherwise the host has no display). See the Single-GPU-Passthrough guide for the full procedure.

❌ Anti-cheat detects my VM — what now?

EAC and BattlEye can run natively under Linux/Proton if the game's developer enables it — check Heroic / ProtonDB and play on the Linux host instead. Vanguard (Valorant), FACEIT and many EAC/BattlEye titles do detect or block VM environments. There is no fully reliable workaround beyond the techniques above.

❌ My CPU doesn't have VT-d / AMD-Vi

GPU passthrough is not possible. The IOMMU hardware feature is mandatory. Many older Intel consumer CPUs (especially pre-Skylake "K" models) lack VT-d; on older AMD platforms support depends on the chipset/board (all Ryzen platforms have AMD-Vi). Check the CPU virtualization list.

❓ Still stuck?

→ Arch Wiki: PCI passthrough via OVMF is the canonical reference. The r/VFIO subreddit is extremely helpful.