If you've ever tried to run Plex, Jellyfin, or a Windows gaming VM inside Proxmox and hit a wall of choppy transcoding or unplayable frame rates, the fix is usually the same: stop asking the virtual machine to share the host's software rendering and give it a real graphics card instead. That's what GPU passthrough does. You hand a physical GPU straight to a virtual machine, and the VM treats it exactly like a card plugged into a real motherboard slot — because, electrically, it basically is.

This is one of those features that sounds terrifying the first time you read about it — IOMMU groups, VFIO, kernel modules — and then turns out to be a fairly short list of steps once you know what each one is actually doing. That's the goal here: walk through a working setup on a fresh Proxmox VE 8.x or 9.x host, explain what each command does as you go, and flag the handful of things that trip up almost everyone the first time.

What You Will Learn

By the end of this guide you'll know what IOMMU and VFIO actually are and why Proxmox needs both before it will let go of a GPU. You'll check whether your CPU and motherboard even support passthrough, turn on the right BIOS setting, and configure the Proxmox host to release the card at boot instead of grabbing it for itself. Then you'll attach that GPU to a virtual machine and confirm it's showing up correctly inside the guest. We'll also cover the errors that show up most often — a VM that refuses to start, or a "reset" the GPU won't recover from — and how to work through them.

What Is This Feature?

PCI passthrough is the general mechanism: Proxmox takes a physical PCI or PCIe device — a graphics card, a network card, sometimes a whole USB controller — and hides it from the host operating system entirely, so a single VM can control it directly instead of going through a shared, emulated driver.

Two pieces make this possible. The first is IOMMU (Input-Output Memory Management Unit), a feature built into modern Intel and AMD CPUs and chipsets. It lets the hardware safely redirect a device's memory access to a specific VM instead of the host, and it's what stops a passed-through device from being able to read or write memory it has no business touching. Without IOMMU support, passthrough isn't just harder — it's not possible at all, because there's no hardware guarantee keeping the VM's access contained.

The second piece is VFIO (Virtual Function I/O), the Linux kernel framework that actually detaches a device from its normal driver and hands it to a VM through vfio-pci. Think of it as the handoff mechanism: IOMMU makes the separation physically safe, and VFIO is what performs the handoff.

GPU passthrough is the most popular use of this, because a GPU is the one component where emulation genuinely isn't good enough — Proxmox's default display output for a VM is fine for a desktop OS, useless for 4K transcoding or gaming.

Why Would You Use It?

The honest answer is: only when software rendering genuinely isn't enough. A few situations where that's true:

  • Hardware transcoding for media servers. Plex, Jellyfin, and Emby can offload video transcoding to a GPU's dedicated encoder, which is dramatically faster and lighter on CPU than software transcoding four or five simultaneous streams.
  • Gaming VMs. Running Windows in a VM with a passed-through GPU gets you close to native gaming performance — this is the whole premise behind "single GPU passthrough" setups people build for a dedicated gaming rig that also happens to run Proxmox.
  • GPU-accelerated workloads. Machine learning, video editing, or CAD software inside a VM that needs real CUDA or OpenCL access, not a software fallback.

If none of that describes what you're doing, skip this. A VM using the default display adapter is perfectly fine for a file server, a Home Assistant instance, or basically anything that isn't rendering graphics or encoding video. Passthrough adds real complexity — you're giving up the ability to use that GPU on the host, and recovering it if a VM crashes badly isn't always clean.

Prerequisites

  • A CPU and motherboard that both support IOMMU — Intel calls this VT-d, AMD calls it AMD-Vi. Check your motherboard's BIOS manual if you're not sure it's there.
  • Proxmox VE 8.x or 9.x already installed and reachable over SSH or the web console.
  • A second GPU, or an iGPU, for the Proxmox host itself if you're passing through your only discrete card — you'll lose console output on that card once passthrough is active.
  • Root access to the host shell.
  • A Windows or Linux VM already created in Proxmox, ready to have the GPU attached — this guide assumes the VM itself exists already.

Step-by-Step Tutorial

Step 1: Turn on IOMMU in the BIOS

Reboot into your BIOS/UEFI setup and look for a setting called Intel VT-d or AMD-Vi / IOMMU, usually tucked under a CPU or chipset configuration menu. Enable it and save. The exact menu wording varies wildly between motherboard vendors, so if you can't find it, search your board's exact model number plus "VT-d" — nearly every manufacturer names it slightly differently.

Step 2: Add the IOMMU kernel parameter

Proxmox needs to know to enable IOMMU at boot too, not just the BIOS. How you do this depends on which bootloader your install uses, and this is the step that trips people up more than any other — editing the wrong file silently does nothing.

Check which one you're running:

proxmox-boot-tool status

If that reports your boot disk is managed, you're on systemd-boot — the default when Proxmox is installed on ZFS. Edit /etc/kernel/cmdline and add the parameter to the existing line, so it looks like this on an Intel system:

root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt

On AMD, IOMMU is on by default in recent kernels, but adding iommu=pt (IOMMU passthrough mode, which improves performance for devices that don't need translation) is still worth doing.

Then apply it:

proxmox-boot-tool refresh

If you're on a traditional GRUB setup instead (typical on ext4/LVM installs), edit /etc/default/grub and find the GRUB_CMDLINE_LINUX_DEFAULT line:

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

Then rebuild the config:

update-grub

Reboot after either method. This step doesn't take effect until the machine actually restarts.

Step 3: Confirm IOMMU is actually active

After rebooting, check the kernel log:

dmesg | grep -e DMAR -e IOMMU -e AMD-Vi

You're looking for a line mentioning "IOMMU enabled" or, on Intel, something like "DMAR: IOMMU enabled." If you see nothing at all, double-check the BIOS setting from Step 1 first — that's the far more common culprit than a typo in the kernel parameter.

Step 4: Load the VFIO kernel modules

Add these four lines to /etc/modules:

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

Then rebuild the initramfs so the modules load early enough at boot to grab the GPU before the host's own graphics driver does:

update-initramfs -u -k all

Step 5: Find your GPU's IOMMU group and PCI IDs

Not every GPU can be passed through cleanly — it depends on how the motherboard groups PCI devices together internally. List your PCI devices and note the one you want:

lspci -nn | grep -i nvidia

(swap nvidia for amd or vga if you're using a different card). You'll get a line like:

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484]

The bracketed pair at the end — 10de:2484 — is the vendor:device ID you'll need in the next step. Most GPUs also have a second function for HDMI audio, usually at the same bus address with .1 instead of .0 — grab that ID too, since both need to move to the VM together.

Step 6: Bind the GPU to vfio-pci instead of its normal driver

Create a config file telling the vfio-pci driver to claim those IDs before the GPU's usual driver gets a chance to:

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

(replace both IDs with your actual GPU and audio function IDs from Step 5). Rebuild initramfs again and reboot:

update-initramfs -u -k all
reboot

Step 7: Verify the card is bound to vfio-pci

lspci -nnk

Find your GPU's entry in the output and check the "Kernel driver in use" line underneath it. It should say vfio-pci, not nvidia, nouveau, or amdgpu. If your usual driver is still listed, the card is being grabbed before vfio-pci gets to it — see the Troubleshooting section below.

Step 8: Attach the GPU to the VM

In the Proxmox web UI, open the VM, go to Hardware, and click Add → PCI Device. Select your GPU from the list, and tick All Functions so the audio function comes along with it. If it's your primary GPU and you want it as the VM's actual display output, also tick Primary GPU.

Or do the same thing from the shell:

qm set 100 -hostpci0 01:00,pcie=1,x-vga=1

(replace 100 with your VM's ID, and 01:00 with your GPU's bus address from Step 5, without the function number).

For best results, set the VM's machine type to q35 and BIOS to OVMF (UEFI) under the VM's Options tab — both settings live in the same tab. q35 gives the VM a more modern, PCIe-native chipset emulation, which passthrough GPUs generally behave better under than the older i440fx default.

Commands Explained

CommandWhat it does
proxmox-boot-tool statusReports whether your install uses systemd-boot or GRUB, which determines where kernel parameters need to go.
proxmox-boot-tool refreshReapplies boot configuration on systemd-boot systems after editing /etc/kernel/cmdline.
update-grubRegenerates the GRUB configuration after editing /etc/default/grub, so new kernel parameters actually get applied.
update-initramfs -u -k allRebuilds the initial RAM disk for every installed kernel, needed after changing /etc/modules or adding a vfio.conf file.
lspci -nnLists PCI devices along with their vendor:device IDs in brackets — what you need for the vfio.conf entry.
lspci -nnkSame as above, plus which kernel driver currently has each device claimed — used to confirm vfio-pci actually took over.
qm set <vmid> -hostpci0 <bus>Attaches a PCI device to a VM's configuration at the given bus address, from the command line instead of the GUI.

Common Errors

  • VM fails to start with "vfio: error opening /dev/vfio/X: No such device." The vfio-pci module didn't actually claim the GPU. Recheck Step 7 — if the driver in use still shows your normal GPU driver, the vfio.conf file either has the wrong IDs or wasn't picked up because initramfs wasn't rebuilt afterward.
  • "IOMMU not enabled" or the VM refuses to add the PCI device at all. Almost always means Step 1 or Step 2 didn't actually take — either the BIOS setting is off, or you edited GRUB's config on a systemd-boot system (or vice versa) and the parameter never applied.
  • Everything works, then a VM reboot leaves the GPU unusable until the whole host reboots. This is a GPU reset issue — the card doesn't support a clean function-level reset (FLR), so it comes back in a broken state the second time a VM claims it. Consumer NVIDIA cards are especially known for this.
  • Windows shows "Code 43" for the GPU in Device Manager. NVIDIA drivers detect they're running in a VM and refuse to initialize properly. This needs a couple of extra VM config tweaks — hiding the hypervisor bit and setting kvm=off — that go beyond basic passthrough setup, but it's a known and well-documented workaround if you hit it.

Troubleshooting

If the GPU's driver keeps grabbing the card before vfio-pci can, the fix is usually to blacklist that driver on the host entirely, since the host has no legitimate use for it once the card is dedicated to a VM:

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

Rebuild initramfs and reboot after adding blacklist entries, same as any other module change.

If IOMMU groups are the problem — meaning your GPU shares a group with unrelated devices you can't also pass through — there isn't always a software fix. Some motherboards isolate PCIe slots into clean, separate groups by default; others lump several slots together at the chipset level, and no amount of kernel parameter tweaking changes that. This is genuinely a hardware limitation, and it's worth checking your board's IOMMU grouping behavior before buying hardware specifically for a passthrough build.

For the "reset bug" where a VM reboot leaves the card unusable, look into vendor-reset, a community kernel module that adds proper reset support for AMD cards known to lack clean FLR. There's no equivalent fix for most affected NVIDIA cards — a full host reboot is often the only reliable recovery.

Best Practices

  • Always have a second display path into the host — an iGPU, a second card, or at minimum SSH access — before you take your only GPU away from Proxmox's own console output.
  • Pass through both the GPU and its audio function together. Splitting them across VMs, or leaving the audio function bound to the host, causes more subtle breakage than it's worth troubleshooting.
  • Stick with q35 and OVMF for any GPU passthrough VM. The older i440fx and SeaBIOS combination technically works in some cases, but you'll hit more driver quirks for no real benefit.
  • Snapshot the VM's configuration (not a live snapshot, just note the working hostpci0 line) once passthrough is working. If you ever need to rebuild the VM, you'll want that exact syntax on hand.
  • Don't attempt this on your very first Proxmox VM. Get comfortable creating and managing regular VMs first — passthrough adds a layer of hardware-specific troubleshooting you don't want stacked on top of also learning Proxmox basics.

Frequently Asked Questions

Do I need two GPUs to do this?

Not strictly — single-GPU passthrough is possible using scripts that unbind the card from the host right before starting the VM and rebind it after. It's more fragile than a two-GPU setup, so if you have the option to add a cheap second card or use an iGPU for the host, it's worth it.

Will this work with any GPU?

Most modern GPUs support the basic passthrough mechanism, but not all handle the reset cycle cleanly, and IOMMU grouping depends on your motherboard, not the GPU. Check your specific card and board combination before assuming it'll work.

Can I still use the passed-through GPU on the Proxmox host?

No. Once it's bound to vfio-pci, the host can't use it for anything — no console output, no host-side transcoding. It belongs entirely to whichever VM it's attached to.

Does this affect Proxmox VE 8 differently than 9?

The steps here apply to both. The main practical difference is that fresh Proxmox VE installs increasingly default to ZFS and systemd-boot rather than GRUB, so double-check which bootloader you're on with proxmox-boot-tool status rather than assuming.

What if I want to pass the GPU to an LXC container instead of a VM?

That's a different mechanism — LXC containers share the host kernel, so passthrough there means exposing device nodes directly rather than using vfio-pci and IOMMU isolation. It's a separate setup process from what's covered here.

Conclusion

GPU passthrough looks like a wall of unfamiliar acronyms right up until you've done it once. IOMMU makes the isolation safe, VFIO does the actual handoff, and everything else is really just making sure the host lets go of the card before your VM asks for it. The one thing worth repeating: check your bootloader before editing kernel parameters, because that single mismatch — GRUB edits on a systemd-boot system, or the reverse — is behind more "it's just not working" reports than anything else in this guide.

Once it's running, a passed-through GPU inside a VM behaves like real hardware, because for every practical purpose, it is. Whether that's a Plex server suddenly transcoding four 4K streams without breaking a sweat, or a Windows gaming VM that finally feels native, it's one of the more satisfying things you can get a homelab box to do.