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
VFIO Driver
Isolation
Direct Access
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
Step 2: Enable IOMMU in Kernel Parameters
Edit your bootloader config to enable IOMMU at the kernel level. For GRUB, edit /etc/default/grub:
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 reboot
Step 3: Verify IOMMU Groups
After reboot, check your IOMMU groups to ensure devices are properly isolated:
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:
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 update-initramfs -u # Ubuntu/Debian
Step 5: Install Virtualization Software
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 usermod -aG libvirt $USER
Step 6: Create the VM in Virt-Manager
- Open Virt-Manager and click "Create a new virtual machine"
- Choose "Local install media" and select your Windows ISO
- Allocate at least 8GB RAM and 4 CPU cores
- Important: Select "Customize configuration before install"
- 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)
- In CPUs, check "Copy host CPU configuration"
- Remove the default video adapter (Spice/QXL)
- Click "Add Hardware" → "PCI Host Device" → Select your GPU
- 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:
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_idto 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-passthroughin VM XML (nothost-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 usewritebackcache
❌ 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.