Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Windows 10 KVM with GPU Passthrough

Verify PCI Passthrough Support

Intel systems may need intel_iommu=on added as a kernel parameter. Then verify that IOMMU is enabled:

$ dmesg | grep -i -e DMAR -e IOMMU

Next, use the following shell script to check IOMMU groups. The IOMMU group of the GPU must not include any devices that need to remain connected to the host.

#!/bin/bash

shopt -s nullglob

for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
    echo "IOMMU Group ${g##*/}:"
    for d in $g/devices/*; do
        echo -e "\t$(lspci -nns ${d##*/})"
    done;
done;

Prerequisites

Install the following Arch packages:

  • libvirt
  • virt-manager
  • qemu-desktop
  • edk2-ovmf
  • iptables-nft
  • dnsmasq
  • looking-glass
  • samba

Download the following images:

Add the vfio modules to /etc/mkinitcpio.conf and rebuild initramfs:

MODULES=(... vfio_pci vfio vfio_iommu_type1 vfio_virqfd ...)

Then add a kernel parameter to bind the vfio-pci module to the GPU PCI IDs:

vfio-pci.ids=10de:1c03,10de:10f1

Create Virtual Machine with virt-manager

  • Create a new VM with Windows 10 install ISO
  • 16 GB memory (or half available memory)
  • 6 CPUs (or half available CPUs)
  • Custom storage, VM Storage Pool, 500 GB qcow2 disk
  • Network: NAT

Customize configuration before install:

  • Firmware: UEFI
  • Manually specify CPU topology:
    • sockets = number of physical CPU sockets
    • cores = number of physical CPU cores / 2
    • threads = number of physical CPU threads per core
  • Switch disk to virtio
  • Switch NIC to virtio
  • Disable NIC for Windows install
  • Remove console device
  • Add a second CDROM device with the VirtIO driver ISO
  • Set CDROM device 1 as primary boot device

Then go through the Windows install procedure. Load the VirtIO storage driver from the amd64/win10 folder on the second CDROM drive.

Configure Passthrough GPU with Looking Glass

  • Verify that the display device is set to Spice
  • Remove the Tablet device
  • Add PCI Host devices for the dedicated GPU (video and audio may be separate devices)

Make the following edits to the virtual machine XML config, under <devices>:

<shmem name='looking-glass'>
  <model type='ivshmem-plain'/>
  <size unit='M'>32</size>
</shmem>
  • Under <video>, set <model type='vga'/>
  • Add a <input type='mouse' bus='virtio'/> and <input type='keyboard' bus='virtio'/>
  • Disable the memballoon device: <memballoon model="none"/>

Enable Host File Sharing

Add the QEMU schema to the root <domain> XML tag:

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">

Then add the following QEMU options after </devices> to enable host file sharing via Samba:

<qemu:commandline>
  <qemu:arg value="-net"/>
  <qemu:arg value="user,smb=/path/to/shared/folder"/>
  <qemu:arg value="-net"/>
  <qemu:arg value="nic,model=virtio"/>
</qemu:commandline>

If the libvirt throws a permission denied error accessing the shared path, edit /etc/libvirt/qemu.conf to run QEMU as root. seccomp must also be disabled or QEMU will crash when trying to launch Samba:

user = "root"
group = "root"
seccomp_sandbox = 0

Configure Windows

Configure Windows using the built-in display in virt-manager:

  • Install the VirtIO drivers and virtio-win-guest-tools from the second CDROM drive
  • Install the Looking Glass host application
  • Install the graphics driver for the passthrough GPU
  • In mouse settings, disable “Enhance pointer precision”
  • Download Custom Resolution Utility and add a custom resolution equal to the size of the Looking Glass client window.
  • Map a network drive to \\10.0.2.4\qemu to access the host shared folder