Files
scripts/portainer-compose-stacks/windows/GPU-PASSTHROUGH.md
2025-11-22 14:48:58 +02:00

5.5 KiB

AMD Strix Halo iGPU Passthrough to Windows Container

This guide configures PCI passthrough for the AMD Strix Halo integrated GPU to the Windows Docker container, enabling GPU-accelerated applications.

Important Note: Manual Binding Approach

This setup uses manual GPU binding to avoid host display issues. The GPU remains available to the host by default, and you manually bind it to VFIO only when starting the Windows container. This prevents system freezing at boot on newer kernels.

Problem

The Windows container was showing "Red Hat VirtIO GPU DOD Controller" instead of the AMD GPU because:

  • IOMMU was disabled (amd_iommu=off)
  • GPU was not passed through at PCI level
  • Only /dev/dri devices were exposed (insufficient for Windows)
  • Early VFIO binding caused host display to freeze

Solution Overview

  1. Enable AMD IOMMU in kernel boot parameters
  2. Bind GPU and audio devices to vfio-pci driver
  3. Configure QEMU to pass through PCI devices
  4. Restart container and install AMD drivers in Windows

Hardware Details

  • GPU: AMD Strix Halo iGPU (PCI: c5:00.0, ID: 1002:1586)
  • Audio: HDMI Audio Controller (PCI: c5:00.1, ID: 1002:1640)

Setup Instructions

Step 1: Fix GRUB Configuration (If You Had Freezing Issues)

If your system was freezing at login on newer kernels:

cd /mnt/shared/DEV/repos/d-popov.com/scripts/portainer-compose-stacks/windows
sudo ./fix-grub-remove-vfio-ids.sh

This removes early VFIO binding that causes the host to lose GPU access.

Step 2: Update GRUB and Reboot

sudo update-grub
sudo reboot

IMPORTANT: After reboot, IOMMU will be enabled but GPU remains available to host.

Step 3: Before Starting Windows Container - Bind GPU

Every time you want to use GPU passthrough, run:

cd /mnt/shared/DEV/repos/d-popov.com/scripts/portainer-compose-stacks/windows
sudo ./bind-gpu-to-vfio.sh

This temporarily binds the GPU to VFIO (host display will stop working).

Step 4: Start Windows Container

cd /mnt/shared/DEV/repos/d-popov.com/scripts/portainer-compose-stacks/windows
docker compose up -d

Step 5: When Done - Restore GPU to Host

After stopping the Windows container, restore GPU to host:

cd /mnt/shared/DEV/repos/d-popov.com/scripts/portainer-compose-stacks/windows
sudo ./unbind-gpu-from-vfio.sh

This rebinds the GPU to amdgpu driver for host use.

Step 6: Install AMD Drivers in Windows

  1. Connect to Windows via RDP: localhost:3389
  2. Open Device Manager
  3. You should see "AMD Display Adapter" (may show with warning)
  4. Download AMD Radeon drivers for Windows 11
  5. Install the drivers
  6. Reboot Windows
  7. Verify GPU in Task Manager → Performance → GPU

Docker Compose Configuration

The configuration includes:

environment:
  GPU: "Y"
  ARGUMENTS: "-device vfio-pci,host=c5:00.0,addr=0x02,multifunction=on -device vfio-pci,host=c5:00.1,addr=0x02.1"
devices:
  - /dev/vfio/vfio

This passes through:

  • c5:00.0: AMD GPU
  • c5:00.1: HDMI Audio
  • addr=0x02: Virtual PCI slot in guest
  • multifunction=on: Allows multiple functions on same slot

Troubleshooting

GPU still shows VirtIO after reboot

Check if GPU is bound to vfio-pci:

lspci -nnk -s c5:00.0

Should show: Kernel driver in use: vfio-pci

If not, manually bind:

echo "0000:c5:00.0" | sudo tee /sys/bus/pci/drivers/amdgpu/unbind
echo "1002 1586" | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id

IOMMU not enabled after reboot

Check kernel parameters:

cat /proc/cmdline | grep iommu

Should show: amd_iommu=on iommu=pt

If not present:

sudo nano /etc/default/grub
# Add to GRUB_CMDLINE_LINUX_DEFAULT: amd_iommu=on iommu=pt
sudo update-grub
sudo reboot

Container fails to start

Check logs:

docker logs windows

Common issues:

  • VFIO device not found: Run verification script
  • Permission denied: Ensure container is privileged: true
  • Device busy: Another driver may be using the GPU

GPU not detected in Windows

  1. Check Device Manager for unknown devices
  2. Try installing AMD Chipset drivers first
  3. Use AMD Auto-Detect tool for driver installation
  4. Check Windows Event Viewer for driver errors

Performance Notes

  • Full GPU acceleration: Direct PCI passthrough provides near-native performance
  • VRAM: Windows will see the full iGPU VRAM allocation
  • Display output: Use RDP/VNC (no physical display from container)
  • 3D acceleration: Fully supported (DirectX, OpenGL, Vulkan)

Limitations

  • Host cannot use the iGPU while passed through to the container
  • Physical display outputs from the GPU won't work (headless only)
  • USB devices may need separate passthrough configuration
  • Some GPU features may require CPU pinning for best performance

Files Modified

  • /etc/default/grub - IOMMU kernel parameters
  • /etc/modprobe.d/vfio.conf - VFIO driver binding
  • /etc/initramfs-tools/modules - VFIO modules in initramfs
  • docker-compose.yml - PCI passthrough arguments

Reverting Changes

To restore GPU to host:

  1. Remove VFIO configuration:
sudo rm /etc/modprobe.d/vfio.conf
  1. Edit GRUB to remove vfio-pci.ids=...:
sudo nano /etc/default/grub
sudo update-grub
  1. Update initramfs and reboot:
sudo update-initramfs -u
sudo reboot

References