Although the title state this is for the GPD WIN2 it should work with any supported Intel iGPUs.
GVT-G is an Intel technology that provides Intel iGPU passthrough in virtual machine using KVM. It's only compatible with Intel's newer CPU.
GPD WIN2 with Niluanxy's cooling mod installed :
iGPU : HD Graphics 615 CPU : M3-7Y30 4Core@2.6GHz HOST : MANJARO-5.5.2-1 GUEST : Windows 10 1909 BIOS: BIOS
GPD P2 MAX :
iGPU : UHD Graphics 615 CPU : M3-8100Y 4Core@3.4GHz HOST : MANJARO-5.5.2-1 GUEST : Windows 10 1909 BIOS: BIOS
If you don't want to bother configuring the VM yourself I'm providing helper scripts to setup/start the VM.
However HOST grub and initramfs config should be done manually ! Refer to this section
Use setup.sh once only to setup your host configuration. Use start.sh each time you want to boot the VM
Setup script usage ./helpers/setup.sh iso_image vm_size in GB.
Start script usage ./helpers/start.sh vm_name ram_ratio_allocation_size.
ram_ratio_allocation_size is optional and should be in range [1-4].
It allocates X/4 * Total_RAM amount ( default is 3/4 )
Examples :
setup.sh :
sudo ./helpers/setup.sh windows.iso 50G
start.sh :
sudo ./helpers/start.sh windows 3
- Linux Host with Kernel 5.5
- KVM
- Virtio iso
- UEFI VBIOS
- Windows 10 iso
- CPU Governor
Use only Linux 5.5 as Linux 5.4 and some previous version don't work for this setup. *You should be able download the 5.5.2 kernel from your distro package manager otherwise compile it yourself following intel/gvt gvt-g setup guide, you can use vanilla linux instead of intel's kernel.
Check if your CPU supports VT-x/VT-d :
LC_ALL=C lscpu | grep VirtualizationCheck if KVM is loaded in the kernel :
zgrep CONFIG_KVM /proc/config.gzYou have to use the latest master version of capstone for qemu to build properly.
git clone https://github.com/aquynh/capstone/cd capstonesudo ./make.sh
According to this comment modify the display's refresh rate in QEMU :
git clone https://git.qemu.org/git/qemu.gitEdit qemu/include/ui/console.h and change GUI_REFRESH_INTERVAL_DEFAULT = 30 to 16/17 milliseconds for 60Hz refresh rate ( to calcute your refresh rate timing use this formula : ( 1/REFRESH_RATE_IN_HERTZ*1000 ) ) :
GUI_REFRESH_INTERVAL_DEFAULT = 17Build QEMU :
git submodule update --init roms/seabios./configure --prefix=/usr \
--enable-kvm \
--disable-xen \
--enable-libusb \
--enable-debug-info \
--enable-debug \
--enable-sdl \
--enable-vhost-net \
--enable-spice \
--disable-debug-tcg \
--enable-opengl \
--enable-gtk \
--target-list=x86_64-softmmumake -j$((`nproc`/2)) ### or `make -j${nproc}` to use all corecd roms/seabiosmake -j$((`nproc`/2)) ### or `make -j${nproc}` to use all corecd ../..sudo make install
sudo cp roms/seabios/out/bios.bin /usr/bin/bios.bin
These configurations where made using Manjaro, tweak to reflect your distribution config.
Add the following modules to your be loaded with initramfs :
MODULES = 'kvmgt vfio_pci vfio vfio-iommu-type1 vfio-mdev vfio_virqfd'
Append the following to GRUB_CMDLINE_DEFAULT inside /etc/default/grub :
GRUB_CMDLINE_DEFAULT="... i915.enable_gvt=1 kvm.ignore_msrs=1 intel_iommu=igfx_off i915.enable_guc=0 ..."And update GRUB :
sudo update-grub
Edit /etc/libvirt/qemu.conf :
Uncomment this line and replace root by your username if you want to allow a specific user other than root to launch qemu :
user="azkali" ## Replpace with your own usernameAllow audio playing :
nographics_allow_host_audio = 1TODO
Append the following inside <domain> replace RAM_KiB by the amount of RAM to allocate in KiB :
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
................
<memory unit='KiB'>RAM_KiB</memory>
<currentMemory unit='KiB'>RAM_KiB</currentMemory>
................
Append the following inside <domain> under <currentMemory> :
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
................
<memory unit='KiB'>RAM_KiB</memory>
<currentMemory unit='KiB'>RAM_KiB</currentMemory>
<memoryBacking>
<hugepages/>
<nosharepages/>
<discard/>
</memoryBacking>
................
TODO
.........
</devices>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
</qemu:commandline>
</domain> .........
</devices>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.ramfb=on'/>
</qemu:commandline>
</domain> .........
</devices>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.romfile=/var/lib/libvirt/images/vbios_gvt_uefi.rom'/>
</qemu:commandline>
</domain>At this point you're pretty much setup. Either configure a SPICE or VNC server as display.
More on Arch Wiki.
Or
Append the following to your xml file to use QEMU GTK display :
..........
</devices>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.driver=vfio-pci-nohotplug'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.display=on'/>
<qemu:arg value='-display'/>
<qemu:arg value='gtk,gl=on'/>
<qemu:env name='DISPLAY' value=':1'/>
<qemu:env name='GDK_SCALE' value='1.0'/>
<qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
<qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
</qemu:commandline>
</domain>If using QEMU GTK display, set display in $DISPLAY variable before every launching the VM :
xhost si:localuser:nobodyYour final <qemu:commandline> should look like this :
..........
</devices>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.romfile=/var/lib/libvirt/images/vbios_gvt_uefi.rom'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.ramfb=on'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.driver=vfio-pci-nohotplug'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.display=on'/>
<qemu:arg value='-display'/>
<qemu:arg value='gtk,gl=on'/>
<qemu:env name='DISPLAY' value=':1'/>
<qemu:env name='GDK_SCALE' value='1.0'/>
<qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
<qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
</qemu:commandline>
</domain>Attach a new SATA disk with qcow2 format :
qemu-img create -f qcow2 Win10.qcow2 50G ## Set to at least 30G for Windows 10 1909TODO
- Add a new CD-ROM device pointing to your
Windows10.isofile location - Boot up the VM
- Install Windows 10
- Shutdown Windows 10 as you would normaly
- Remove Windows 10 CD-ROM
- Add a new CD-ROM device pointing to your
virtio.isofile location - Boot your VM
- Open the virtio drive (
My PC -> CD-ROM..) - Execute and install the
*_64.exefile with default options - Shutdown Windows 10 as you would normaly
- Remove
virtio.isoCD-ROM
You can now use virtio driver for your storage and network devices.
In virt-manager select your disk device and change the driver to VirtIO
- Install the latest Intel graphics drivers or let Windows do the job
- You will see a black screen for a bit, wait until you get back to windows ( it should take under a few minutes )
- Then open your
Device Manager->Displayyou should see your iGPU being properly installed, for meHD Graphics 615
Setting up the CPU topology statically should improve performances. As both th P2MAX and the WIN2 have only 1 CPU [[[]]], CPU pinning shouldn't be needed.
More on Arch Wiki and RedHat Guide
More on Arch Wiki
If you intend to play some games or graphical tasks I highly recomand to setup a CPU governor, at least for the GPD devices.
You can use my setup for TLP and Intel-undervolt inside examples folder.
Refer to this RedHat guide about virtualization tuning and optimization.
Set suspend-to-mem and suspend-to-disk to yes:
<pm>
<suspend-to-mem enabled='yes'/>
<suspend-to-disk enabled='yes'/>
</pm>Enable tuned service to set profile for kvm
chmod -x /usr/lib/evolution/evolution-calendar-factory to disable evolution
- Audio passthrough - add section
- Samba server - add section
- CPU Pinning
- Static Hugepages
- Guest sleep - add section
- NUMA - add section
- Tuned - add section
- KSM - Kernel Same Page - add section
- ksmtuned enabled - add section
- numactl - add section
- UEFI - Untested should work
- Clipboard
- Using RAW filesystem - add section
- Virtio Net & Disk drivers - add section
- Partition as storage - add section
- SD Card passthrough - not possible requires
resetcapabilities - USB passthrough - not possible requires
resetcapabilities
Redhat - Virtualiaztion Tuning and Optimization
Arch Wiki - PCI passthrough via OVMF Arch Wiki - Intel DMA_BUF Arch Wiki - Intel RAMFB Display
Reddit - WIN2 Gamepad fix Reddit - WIN2 Fixes
Github - Intel GVT-G Setup guide Github - Libvirt Hugepage issue