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 [email protected] HOST : MANJARO-5.5.2-1 GUEST : Windows 10 1909 BIOS: BIOS
GPD P2 MAX :
iGPU : UHD Graphics 615 CPU : M3-8100Y [email protected] 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 Virtualization
Check if KVM is loaded in the kernel :
zgrep CONFIG_KVM /proc/config.gz
You have to use the latest master version of capstone for qemu
to build properly.
git clone https://github.com/aquynh/capstone/
cd capstone
sudo ./make.sh
According to this comment modify the display's refresh rate in QEMU :
git clone https://git.qemu.org/git/qemu.git
Edit 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 = 17
Build 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-softmmu
make -j$((`nproc`/2)) ### or `make -j${nproc}` to use all core
cd roms/seabios
make -j$((`nproc`/2)) ### or `make -j${nproc}` to use all core
cd ../..
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 username
Allow audio playing :
nographics_allow_host_audio = 1
TODO
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:nobody
Your 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 1909
TODO
- Add a new CD-ROM device pointing to your
Windows10.iso
file 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.iso
file location - Boot your VM
- Open the virtio drive (
My PC -> CD-ROM..
) - Execute and install the
*_64.exe
file with default options - Shutdown Windows 10 as you would normaly
- Remove
virtio.iso
CD-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
->Display
you 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
reset
capabilities - USB passthrough - not possible requires
reset
capabilities
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