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.


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##*/})"


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:


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>
  • 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="" type="kvm">

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

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

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 \\\qemu to access the host shared folder