Handing a physical card to a guest is a short configuration with a long tail of prerequisites, and when one is unmet the guest simply boots without a GPU and says nothing useful. Checking the conditions first turns a weekend into an hour. This is that checklist, the commands that verify each step, and the architectural cost nobody mentions until afterwards.

Passing a physical GPU into a virtual machine is the one Proxmox feature that reliably consumes a weekend. Not because the configuration is long, but because six separate things must all be true at once, and when one is not, the failure mode is a VM that boots with no GPU and no useful error.

The Six Conditions

Work through these in order. Every one is a hard requirement, and checking them first is faster than debugging afterwards.

RequirementHow to verify
CPU and chipset support IOMMUdmesg | grep -e IOMMU reports it enabled
IOMMU enabled in firmwareVT-d or AMD-Vi set in the BIOS, not just supported
IOMMU enabled in the kernelBoot parameter present, see below
The GPU is in its own IOMMU groupGroup listing shows no unrelated devices
Host drivers are not bound to itnouveau and nvidia blacklisted, vfio-pci bound
The host is not displaying on itConsole on a second GPU or serial, or headless

The fourth row is the one that stops projects. IOMMU groups are decided by the motherboard's PCIe topology, not by configuration, so a group containing your GPU plus a USB controller and a network card means all of those get passed through together or none do. Consumer boards frequently group everything behind one PCIe switch.

Enable IOMMU and Check the Groups

# GRUB: /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
update-grub && reboot

# systemd-boot (a ZFS root install uses this): /etc/kernel/cmdline
# add: intel_iommu=on iommu=pt
proxmox-boot-tool refresh && reboot

Use amd_iommu=on on AMD. Note which bootloader your host uses: a Proxmox install on ZFS root uses systemd-boot, and editing GRUB there changes nothing at all, which is a genuinely common hour lost.

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

Find your GPU. It will appear as two or three functions, typically VGA plus audio, sometimes plus USB and serial on newer cards. All functions of the card must go to the same VM. If the group also contains something the host needs, stop: that board cannot pass this slot cleanly, and the ACS override patch is a workaround that weakens isolation rather than a fix.

Hand the Card to vfio

cat > /etc/modprobe.d/vfio.conf <<'EOF'
options vfio-pci ids=10de:2230,10de:1aef disable_vga=1
EOF

cat > /etc/modprobe.d/blacklist-gpu.conf <<'EOF'
blacklist nouveau
blacklist nvidia
blacklist nvidiafb
blacklist snd_hda_intel
EOF

update-initramfs -u -k all && reboot
lspci -nnk -d 10de:  # driver in use should be vfio-pci

Those vendor and device IDs are examples; use the ones your own lspci -nn reports. Getting them wrong claims the wrong device, and if that device is your network card you have just lost remote access to the host.

That last verification line is the gate. If it still shows nouveau or nvidia, the initramfs was not rebuilt or the blacklist did not take, and no amount of VM configuration will help.

The VM Side

qm set 110 -machine q35
qm set 110 -bios ovmf -efidisk0 local-lvm:1
qm set 110 -cpu host
qm set 110 -hostpci0 01:00,pcie=1,x-vga=1
qm config 110 | grep -E 'machine|bios|hostpci'

Four settings, and three of them are not optional. q35 provides a real PCIe topology rather than the emulated PCI of the default machine type. OVMF means UEFI, which modern GPUs expect. pcie=1 presents the device on PCIe rather than PCI. Passing 01:00 without a function number takes all functions of the card, which is what you want.

Set x-vga=1 only when the guest will drive a display from this card. For a headless compute VM, leave it off and keep the virtual display, which makes the console usable while the GPU does work.

The Failures, and What They Mean

Code 43 in Windows Device Manager. The driver loaded and the card refused. Historically this was the driver detecting a hypervisor; on current Proxmox it is more often a missing OVMF or q35 setting, or a card whose vendor ROM needs supplying explicitly.

The host loses its console on boot. The host was displaying on the card you just took. Either fit a second GPU for the host, use the integrated graphics, or accept a headless host reached over SSH and the web interface.

Passthrough works once, then fails after the VM reboots. The card did not reset properly. Some consumer cards have a well-known reset bug; the reliable answer is a card that resets cleanly, which in practice means a datacenter or professional model rather than a workaround script.

Everything looks right and the guest sees nothing. Check that the guest is not also blacklisting the driver, and check dmesg on the host for vfio errors during VM start. The host log names the reason where the guest cannot.

What Passthrough Costs You

This is the part worth deciding before starting, because it is architectural rather than technical.

A VM with a passed-through PCI device cannot be live-migrated. The device is physically attached to one host, so the guest is pinned there, and that removes the single most valuable property of a Proxmox cluster. Snapshots with memory state are also unavailable for the same reason.

So a GPU VM is a pet, not cattle. Patching its host means shutting the guest down, and a host failure means the guest is down until the host returns. If the workload is a training job that can be restarted, that is a fair trade. If it is a service with an availability commitment, the trade is a poor one and you want a second host with a second card rather than clever configuration. Our runbook for Proxmox maintenance without downtime covers planning windows around guests that cannot move.

Note also that consumer NVIDIA cards do not support vGPU, so one card serves one VM. Splitting a GPU across several guests needs a datacenter card and the vGPU licensing that goes with it, which changes the economics substantially. Our guide to multi-tenant GPU serving covers sharing a card at the application layer instead, which is usually the better answer.

Or Skip the Weekend

Passthrough exists because you own the hardware. If the goal is a GPU rather than the exercise, the same isolation is available without the IOMMU archaeology.

MassiveGRID's GPU instances use bare-metal GPU passthrough with full CUDA core access and no sharing, already configured, on an HA platform. An A100 40GB with 16 vCPUs, 120 GB of RAM and 512 GB of NVMe is $2.26 per hour or $1,649 a month; an A100 80GB is $3.42 or $2,499; an H100 80GB with 32 vCPUs and 480 GB of DDR5 is $5.48 or $3,999. Drivers and ML frameworks are pre-installed. Where you would rather run your own cluster, Proxmox support starts at $99 per node per month and covers the hardware selection that makes passthrough behave, which is most of the battle.

Instances can be ordered across a partner footprint of more than 700 datacenters in 85 metros, 30 countries and six continents, with auto-provisioning in New York, London, Frankfurt and Singapore.

Further Reading