Intel NUC10i7FNH/K + Arch Linux: QEMU/KVM Windows 10 guest with CPU pinning + GPU passthrough with Intel GVT-g + Hugepages
To increase IGD aperture in BIOS, boot in F2, select Advanced
-> Video
-> change IGD Aperture Size
to 2048 MB
Install required packages:
$ sudo pacman -Syy libvirt qemu virt-manager # base packages
$ sudo pacman -Syy edk2-ovmf # for UEFI/OVMF supports
$ sudo pacman -Syy bridge-utils dnsmaq # for network bridge
$ systemctl enable --now libvirtd.service virtlogd.service
$ sudo virsh net-start default # run this if the NAT interface isn't up automatically
Then create the VM inside virt-manager
, namely win10
. Remember to set:
Q35
chip set- UEFI/OVMF firmware (
/usr/share/edk2-ovmf/x64/OVMF_CODE.fd
)
Edit the domain with virsh edit
:
$ sudo -E virsh edit win10
Add a new <cputune />
item after <vcpu />
:
<vcpu placement='static'>8</vcpu>
<cputune>
<vcpupin vcpu='0' cpuset='4'/>
<vcpupin vcpu='1' cpuset='5'/>
<vcpupin vcpu='2' cpuset='6'/>
<vcpupin vcpu='3' cpuset='7'/>
<vcpupin vcpu='4' cpuset='8'/>
<vcpupin vcpu='5' cpuset='9'/>
<vcpupin vcpu='6' cpuset='10'/>
<vcpupin vcpu='7' cpuset='11'/>
<emulatorpin cpuset='0,6'/>
</cputune>
Edit <cpu />
item with:
<cpu mode='host-passthrough' check='none' migratable='on'>
<topology sockets='1' dies='1' cores='4' threads='2'/>
</cpu>
Enable kernel modules in /etc/mkinitcpio.conf
:
MODULES=(kvmgt vfio vfio-iommu-type1 vfio-mdev)
and rebuild the initramfs
:
$ mkinitcpio -p linux # for Linux stable kernel
$ mkinitcpio -p linux-lts # for Linux LTS kernel
Enable kernel parameters in /etc/default/grub
:
GRUB_CMDLINE_LINUX_DEFAULT="... intel_iommu=on i915.enable_gvt=1 kvm.ignore_msrs=1"
and rebuild GRUB configs:
$ sudo grub-mkconfig -o /boot/grub/grub.cfg
Reboot and check if mdev_supported_types
exists:
$ ls -la /sys/devices/pci0000:00/0000:00:02.0/mdev_supported_types
(mainly following the official guide)
Create:
$ sudo /bin/sh -c '\
GVT_DOM="0000:00"
GVT_PCI="0000:00:02.0"
GVT_TYPE="i915-GVTg_V5_4"
GVT_GUID="<unique-guid>"
echo "$GVT_GUID" > "/sys/devices/pci$GVT_DOM/$GVT_PCI/mdev_supported_types/$GVT_TYPE/create" \
'
Assign with virsh
:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
...
<devices>
...
<hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='off'>
<source>
<address uuid='<unique-guid>'/>
</source>
</hostdev>
</devices>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.romfile=/home/ethanify/VMs/vbios_gvt_uefi.rom'/>
</qemu:commandline>
</domain>
Run the VM, now Windows will recogise 2 display adapters. Download and install Windows binaries for Spice. After successfully installed, the second adapter will display as Intel Graphic UHD
Edit the domain with virsh
. Remember to remove all <graphics />
and <video />
items first:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
...
<devices>
...
<graphics type='spice'>
<listen type='none'/>
<gl enable='yes' rendernode='/dev/dri/by-path/pci-0000:00:02.0-render'/>
</graphics>
<video>
<model type='none'/>
</video>
<hostdev ... display='on'>
...
</hostdev>
</devices>
<qemu:commandline>
...
<qemu:env name='MESA_LOADER_DRIVER_OVERRIDE' value='i965'/>
</qemu:commandline>
</domain>
Now the VM will run with only Intel Graphic UHD
adapter!
Create a new file /etc/sysctl.d/10-kvm.conf
:
vm.nr_hugepages = 0
vm.nr_overcommit_hugepages = 8192
Use virt-utils.sh
script to:
set-up
mandatory services & procedues prior to VM runningtear-down
the previously set-up services & procedues