Skip to main content

Part 1: Prerequisites

Before we begin, let's install some necessary packages:

sudo apt install libvirt-daemon-system libvirt-clients qemu-kvm qemu-utils virt-manager ovmf

Enable required services sudo systemctl enable --now libvirtd

You should add your user to libvirt group (many times it's automatically done)

usermod -aG kvm,input,libvirt <username>

Restart your machine and boot into BIOS. Enable a feature called IOMMU. You'll also need to enable CPU virtualization. For Intel processors, look for something called VT-d. For AMD, look for something called AMD-Vi. My motherboard is unique so I had to enable a feature called SVM Mode. Save any changes and restart the machine.

Once you've booted into the host, make sure that IOMMU is enabled: dmesg | grep IOMMU

Also check that CPU virtualization is enabled:

  • For Intel: dmesg | grep VT-d
  • For AMD: dmesg | grep AMD-Vi

Now you're going to need to pass the hardware-enabled IOMMU functionality into the kernel as a kernel parameter. For our purposes, it makes the most sense to enable this feature at boot-time. Depending on your boot-loader (i.e. grub, systemd, rEFInd), you'll have to modify a specific configuration file. Since my machine uses systemd and these configuration files are often overwritten on updates, I will be using a tool called kernelstub:

  • For Intel: sudo kernelstub --add-options "intel_iommu=on"
  • For AMD: sudo kernelstub --add-options "amd_iommu=on"

Similarly, if your system is configured with GRUB2, you can achieve the same result by editing the /etc/default/grub file with sudo permissions and including the kernel parameter as follows:

  • For Intel: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"
  • For AMD: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on"

Edit /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"

or for AMD

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on"

2. Creating a stub for the GPU

Next, we need to update the kernel command line to configure vfio-pci to consume each passthrough device to prevent it from being used by the hypervisor. If using GRUB, add another argument to GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub in the following format (where PLACEHOLDER should be replaced with a comma-separated list of hardware IDs for your passthrough devices):

vfio_pci.ids=PLACEHOLDER

Once you modify this variable, it should look similar to the following example:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on vfio_pci.ids=10de:1c03,10de:10f1"