Linux KVM GPU pass-through with identical graphic cards

Linux KVM GPU pass-through with identical graphic cards

Passing-through a GPU to a virtual machine requires loading vfio-pci, instead of the "normal" GPU driver. Normally you use the device-ids to select the graphic card for the virtual machine, but what if they share the same id?

In a previous guide, we looked at how to pass-through an GPU on AMD Ryzen ThreadRipper Systems to Windows 10. As long as you have different GPU models, this is straightforward. If not, it's more complicated, as vfio-pci only supports device-ids as parameters.

In this tutorial two AMD Radeon Vega 64 GPUs are used, sharing the same device ids. Linux distribution is Gentoo, but any other distribution should work too.

$ lspci | grep -i vga
0c:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Vega 10 XL/XT [Radeon RX Vega 56/64] (rev c1)
44:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Vega 10 XL/XT [Radeon RX Vega 56/64] (rev c3)

Preventing the load of the GPU driver

First step is preventing the GPU driver (in this case amdgpu) to be loaded during the boot. Depending on your distribution putting a blacklist amdgpu entry in /etc/modprobe.d/amdgpu.conf could be enough. As an alternative add an kernel boot parameter (modprobe.blacklist=amdgpu) to your grub / systemd-boot configuration.

Unbinding the card

The script needs to be executed before the Display Manager / Xorg is started, so make sure it's either disabled or adjust the init system ordering so the script is executed before it starts.

You can either use virsh or sysfs for unbinding the card and loading vfio-pci for it. After unbinding you can load the GPU driver for the host GPU and start the graphical environment.

#!/usr/bin/env bash

# Unbind sample
# echo 0000:0c:00.0 > /sys/bus/pci/devices/0000:0c:00.0/driver/unbind
# echo 0000:0c:00.0 > /sys/bus/pci/devices/0000:0c:00.0/driver/unbind
virsh nodedev-detach pci_0000_0c_00_0
virsh nodedev-detach pci_0000_0c_00_1

sleep 1

# Load the driver for the host GPU
modprobe amdgpu

Make sure to replace the PCI ids with the ones you want to use (lspci | grep -i vga).

After executing the script, vfio-pci should be loaded for the passed-through GPU.

#  lspci -s 0c:00.0 -v
0c:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Vega 10 XL/XT [Radeon RX Vega 56/64] (rev c1) (prog-if 00 [VGA controller])
    Subsystem: Gigabyte Technology Co., Ltd Vega 10 XL/XT [Radeon RX Vega 56/64]
    ....
    Kernel driver in use: vfio-pci
    Kernel modules: amdgpu