GPU Passthrough on a Mac Pro 6,1 (“trashcan”)

FirePro D500 → Linux desktop on the physical monitor, via Proxmox

Published on July 11, 2026

The goal of this guide is to pass an AMD FirePro D500 (Tahiti GPU, GCN 1.0 architecture, from 2013) from a Mac Pro 6,1 (Late 2013, the “trashcan”) running Proxmox VE into a VM, with the video output appearing on the physical monitor (HDMI/DisplayPort) — not VNC/SPICE.

The result works end-to-end on Linux Mint and Bazzite (Fedora Atomic). On Windows the GPU passes through to the VM without the infamous Code 43, but the physical display doesn't come up — the reason is detailed in the Windows section.

It's an interesting problem because it combines two sources of quirkiness at once: it's a Mac GPU (vBIOS in EFI GOP, not legacy x86) running on 2013-era hardware (no interrupt remapping in the IOMMU). Each of these characteristics alone already requires a specific passthrough adjustment; together, they require a well-defined sequence of steps to work.


Why it's hard (and what each step solves)

The FirePro D500 are Tahiti (GCN 1.0 / Southern Islands) GPUs from 2013, with Mac quirks on top. The table below summarizes the obstacles encountered and the solution applied to each:

Obstacle Symptom Solution
Mac Pro 6,1 has no interrupt remapping vfio: Failed to set iommu for container: Operation not permitted allow_unsafe_interrupts=1
Mac GPU has no x86 vBIOS (uses EFI GOP) Invalid PCI ROM header signature: got 0xffff; GPU doesn't enumerate in the VM extract the real vBIOS and pass it as romfile
The host's amdgpu grabs the GPU at boot and “dirties” it host console on screen; then reset recovery - restoring BARs ... blocked, host may hang early-bind (vfio-pci.ids in the cmdline) — binds the GPU to vfio before amdgpu
x-vga=1 / Mac vBIOS POST in OVMF no signal at boot do NOT use x-vga; use vga: none (VM driver takes over)
Legacy radeon driver doesn't scanout on Tahiti black screen with signal force amdgpu (amdgpu.si_support=1)
Mac's HDMI is HDMI 1.4 (max 4K@30) black with signal at 4K@60 force 1080p/1440p (on Xorg); Wayland/KDE negotiates on its own

Prerequisites

  • Proxmox VE 8/9 on the Mac Pro 6,1; root access via SSH.
  • IOMMU/VT-d available (the Mac Pro's Xeon E5 v2 supports it).
  • One of the two GPUs free for the VM.

Warning: find out which GPU feeds the physical port the monitor is connected to — plug in the monitor and check which card shows connected:

for s in /sys/class/drm/card*/card*/status; do
  [ "$(cat "$s")" = connected ] && echo "$(dirname "$s"|xargs basename) -> PCI $(readlink -f "$(dirname "$s")/../device"|grep -oE '[0-9a-f]{2}:[0-9a-f]{2}\.[0-9]'|tail -1)"
done

On a typical Mac Pro 6,1, the native HDMI is usually fed by the GPU in PCI slot 0000:06:00 (the primary/boot_vga); the other GPU sits at 0000:02:00. Always confirm with the command above before proceeding.

Since both D500s share the same device-id (1002:679e), early-bind by id sends both GPUs to vfio and the host becomes headless (managed via SSH/web). That's intentional and desired here.

Find out your hardware's IDs:

lspci -nn | grep -iE "VGA|Display|Audio"
# Reference: GPU 1002:679e (Tahiti LE), HDMI audio 1002:aaa0, Mac analog audio 8086:1d20 (Cirrus CS4208)

Step 1 — IOMMU + vfio modules (host)

In /etc/default/grub, on the GRUB_CMDLINE_LINUX_DEFAULT line, add intel_iommu=on iommu=pt. In /etc/modules, add vfio, vfio_iommu_type1, and vfio_pci.

# /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="... intel_iommu=on iommu=pt"

# /etc/modules
vfio
vfio_iommu_type1
vfio_pci

Step 2 — allow_unsafe_interrupts (required on the Mac Pro 6,1)

echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf

Without this, vfio refuses (Operation not permitted). Security implication: a malicious VM could, in theory, inject interrupts into the host — acceptable in a single-user/trusted environment; it's the only path on this hardware (which has no interrupt remapping).


Step 3 — Early-bind: the key piece

Bind the GPUs to vfio-pci before amdgpu loads, otherwise the amdgpu initializes the GPU at boot, it gets “dirtied”, and passthrough fails (or hangs the host).

In GRUB_CMDLINE_LINUX_DEFAULT add (use your hardware's IDs):

vfio-pci.ids=1002:679e,1002:aaa0 video=efifb:off

And make sure the driver order is enforced:

printf 'softdep amdgpu pre: vfio-pci\nsoftdep radeon pre: vfio-pci\n' > /etc/modprobe.d/vfio.conf

Apply and reboot the host:

update-grub && update-initramfs -u -k all && reboot

After the reboot, verify (all should be on vfio-pci, and amdgpu should NOT have initialized any of them):

for d in 0000:06:00.0 0000:06:00.1 0000:02:00.0 0000:02:00.1; do echo "$d -> $(basename "$(readlink /sys/bus/pci/devices/$d/driver)")"; done
dmesg | grep -c "amdgpu .*initializing kernel"   # should be 0

Step 4 — Extract the GPU's real vBIOS

The Mac D500s don't expose an x86 expansion ROM, but the vBIOS (atombios) is accessible from the host. The easiest way is to capture it before early-bind (with the GPU still on amdgpu):

cat /sys/kernel/debug/dri/0000:06:00.0/amdgpu_vbios > /usr/share/kvm/d500.rom
# validate: ~64KB, header 55aa, contains "ATOMBIOSBK-AMD ... AMD_TAHITI_LE"
od -A x -t x1 -N 4 /usr/share/kvm/d500.rom   # 55 aa ...

Alternative (always available, even post early-bind): the ACPI VFCT table (/sys/firmware/acpi/tables/VFCT contains the vBIOS + header). Keep copies — it's irreplaceable.


Step 5 — Configure the VM (without x-vga, with romfile, vga: none)

qm set <VMID> -hostpci0 0000:06:00,pcie=1,romfile=d500.rom -vga none
qm set <VMID> -cpu host        # for Windows, use: -cpu host,hidden=1  (anti Code 43)
  • Do not use x-vga=1 (OVMF can't POST the Mac vBIOS → no signal).
  • vga: none makes the physical GPU the only display. The VM must be OVMF/UEFI + q35.

⚠️ With vga: none Proxmox's SPICE/noVNC console won't connect (there's no virtual display). For remote access/installation, use vga: std temporarily; switch to none only in “physical screen” mode.


Step 6 — Force the amdgpu driver inside the VM

The legacy radeon driver loads but doesn't scanout on Tahiti → black screen. Force amdgpu:

Traditional distro (e.g., Linux Mint, Ubuntu, Debian) — in /etc/default/grub:

radeon.si_support=0 amdgpu.si_support=1 amdgpu.cik_support=1

Then update-grub and reboot the VM. (On Mint/Ubuntu grub.d/50_linuxmint.cfg is also read; actually run update-grub — just editing /etc/default/grub.d/ on its own isn't enough.)

Fedora Atomic (e.g., Bazzite, Silverblue/Kinoite) — via kargs:

sudo rpm-ostree kargs --append-if-missing=radeon.si_support=0 --append-if-missing=amdgpu.si_support=1 \
  --append-if-missing=amdgpu.cik_support=1 --append-if-missing=amdgpu.runpm=0

Then reboot the VM. (The amdgpu.runpm=0 is the anti-freeze mitigation — see below.)

⚠️ Kernel 7.0 (Bazzite 44) does NOT eliminate the need for si_support (correcting an earlier observation): the impression that it “wasn't needed” was a lucky boot — there's a radeon×amdgpu race and sometimes neither driver grabs the Tahiti (card0 ends up with no driver → “no signal”). Keep all 3 si_support flags. Atomic image upgrades reset custom kargs → reapply after a major upgrade.

⚠️ amdgpu.runpm=0 is practically mandatory on Bazzite's kernel 7.0/-ogc for passthrough not to hang the ENTIRE HOST: without it, the guest GPU's runtime PM (BACO state) locks up the host's PCIe in a silent deadlock (no AER/MCE; only a power cycle recovers) — consistent with CVE-2026-53293 (amdgpu deadlock, GCN 1.0+, disclosed Jun/2026). With runpm=0 the reset comes out clean (reset done) and the host stays stable (validated: physical boot + VM reboot + usage, no freeze).

Verify on the VM: cat /sys/bus/pci/devices/0000:01:00.0/uevent | grep DRIVERDRIVER=amdgpu.


Step 7 — Resolution, keyboard/mouse, and audio

Resolution: the Mac Pro's HDMI is HDMI 1.4won't display 4K@60 (black with signal). On Xorg (Mint), force 1080p or 1440p (modeline + modesetting). On Wayland/KDE (Bazzite) resolution is negotiated automatically — no need to force it.

Keyboard/mouse: USB passthrough — grab the IDs with lsusb and pass each device:

qm set <VMID> -usb0 host=VVVV:PPPP -usb1 host=WWWW:QQQQ

Works hot-plugged (no need to reboot the VM).

Audio: if the monitor has no speakers, HDMI audio is useless. Pass the Mac's analog codec (on the Mac Pro 6,1 it's a Cirrus CS4208, 0000:00:1b.0) to the VM:

qm set <VMID> -hostpci1 0000:00:1b.0,pcie=1

(shows up as “CS4208 Analog” inside the VM). The Mac Pro 6,1 has two rear analog outputs: headphone (with jack detection) and line out (optical combo — the red light is TOSLINK, harmless). Plug the headphones into the headphone output and select the “Headphone” port in the mixer (KDE/PipeWire) — selecting “Line Out” uses a different codec path and stays silent. Symptom of the wrong path: the Headphone DAC (node 0x02) sits at volume 0x00 with pin 0x10 muted; selecting the right port makes WirePlumber raise the hardware volume and unmute it. On Bazzite (PipeWire) the internal speaker also played without a quirk; on Mint only the rear output works (internal speaker silent without model= on snd_hda_intel).


Pitfalls (learned the hard way)

  • ⚠️ Never reconnect the monitor cable while the VM is running. Display hotplug on a passed-through AMD GPU hangs the entire host kernel (vfio/PCIe freeze) — requires a power cycle. Shut down the VM before touching the cable.
  • ⚠️ If passthrough repeatedly hangs the host, do a full power cycle (power cut ~1 min) — it resets the GPU's hardware state, which a kernel reboot won't undo.
  • After reboots, on unstable networks DHCP for containers/VMs can fail (no network/DNS) → renew with dhclient -1 eth0.
  • The guest agent on Atomic distros (Bazzite) is sandboxed — it won't run privileged binaries via qm guest exec. Write a script to /tmp and run it from the VM's terminal instead.

Windows 10/11 (partial)

The GPU passes through without Code 43 using -cpu host,hidden=1 + the romfile. The card shows up as “AMD Radeon HD 7800 Series” working in Device Manager, with the legacy Adrenalin driver (21.5.2 or 22.6.1).

However the physical display doesn't come up: with vga: none/x-vga OVMF can't POST the Mac vBIOS (no signal), and with a virtual display Windows doesn't detect the monitor on the secondary GPU. Linux works because the KMS driver takes over the GPU at boot; Windows depends on firmware POST. Not solved here.


Rollback

To return the host to its default state: remove vfio-pci.ids, intel_iommu, and video=efifb:off from the cmdline, delete /etc/modprobe.d/{vfio,iommu_unsafe_interrupts}.conf and the vfio modules from /etc/modules, remove hostpci*/usb* from the VM, and switch back to vga: std. Then:

update-grub && update-initramfs -u -k all && reboot

What this guide validates: a physical video output, on a Linux VM, with an AMD FirePro D500 passed through from a Mac Pro 6,1. Always confirm the device-IDs and PCI slots of your own hardware with lspci -nn before reproducing the steps.


Cheat sheet — commands by location

Copy-paste summary of the commands already presented in the sections above, grouped by where each one runs. The device-IDs and PCI slots are from this guide's reference hardware — confirm your own with lspci -nn before copying.

1. Host — /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="... intel_iommu=on iommu=pt vfio-pci.ids=1002:679e,1002:aaa0 video=efifb:off"

2. Host — /etc/modules

vfio
vfio_iommu_type1
vfio_pci

3. Host — /etc/modprobe.d/

# /etc/modprobe.d/iommu_unsafe_interrupts.conf
echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf

# /etc/modprobe.d/vfio.conf
printf 'softdep amdgpu pre: vfio-pci\nsoftdep radeon pre: vfio-pci\n' > /etc/modprobe.d/vfio.conf

4. Host — shell (apply + extract vBIOS + verify)

# apply
update-grub && update-initramfs -u -k all && reboot

# extract vBIOS (before early-bind, with GPU still on amdgpu)
cat /sys/kernel/debug/dri/0000:06:00.0/amdgpu_vbios > /usr/share/kvm/d500.rom

# validate (after reboot; all should be on vfio-pci)
for d in 0000:06:00.0 0000:06:00.1 0000:02:00.0 0000:02:00.1; do echo "$d -> $(basename "$(readlink /sys/bus/pci/devices/$d/driver)")"; done

5. Proxmox — qm (VM config)

# GPU (video)
qm set <VMID> -hostpci0 0000:06:00,pcie=1,romfile=d500.rom -vga none

# CPU (host passthrough)
qm set <VMID> -cpu host

# keyboard/mouse (USB)
qm set <VMID> -usb0 host=VVVV:PPPP -usb1 host=WWWW:QQQQ

# audio (Mac's analog codec)
qm set <VMID> -hostpci1 0000:00:1b.0,pcie=1

6. Linux VM (traditional distro) — /etc/default/grub

radeon.si_support=0 amdgpu.si_support=1 amdgpu.cik_support=1

update-grub

7. Linux VM (Fedora Atomic) — kargs

sudo rpm-ostree kargs --append-if-missing=radeon.si_support=0 --append-if-missing=amdgpu.si_support=1 \
  --append-if-missing=amdgpu.cik_support=1 --append-if-missing=amdgpu.runpm=0

8. VM — verification

cat /sys/bus/pci/devices/0000:01:00.0/uevent | grep DRIVER
# expected: DRIVER=amdgpu