Skip to content

Azkali/GVT-GPD-Win2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GPD WIN2/P2MAX + Intel GVT-G

Although the title state this is for the GPD WIN2 it should work with any supported Intel iGPUs.

GVT-G

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.

My setup

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

AutoInstaller

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

Pre requisites

  • 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

User-Compiled dependencies

Capstone

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

Patched QEMU

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

Linux host config

These configurations where made using Manjaro, tweak to reflect your distribution config.

Initramfs

Add the following modules to your be loaded with initramfs :

MODULES = 'kvmgt vfio_pci vfio vfio-iommu-type1 vfio-mdev vfio_virqfd'

GRUB

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

QEMU as user

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

Libvirt xml config

CPU

TODO

RAM

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>
  ................

Hugepages

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>
  ................

GPU

iGPU Passthrough

TODO

DMA BUF
  .........
  </devices>
  <qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
  </qemu:commandline>
</domain>
RAMFB
  .........
  </devices>
  <qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.ramfb=on'/>
  </qemu:commandline>
</domain>
RAMFB UEFI
  .........
  </devices>
  <qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.romfile=/var/lib/libvirt/images/vbios_gvt_uefi.rom'/>
  </qemu:commandline>
</domain>

Display

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>

Storage

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

Network

TODO

Guest boot

Installation

  • 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

Virtio drivers

  • 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

Use Virtio drivers

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

Intel Graphics

  • 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 me HD Graphics 615

Going further

CPU Optimizations

Pinning

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

Isolating

More on Arch Wiki

Governors

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.

NUMA

Refer to this RedHat guide about virtualization tuning and optimization.

Guest sleep

Set suspend-to-mem and suspend-to-disk to yes:

  <pm>
    <suspend-to-mem enabled='yes'/>
    <suspend-to-disk enabled='yes'/>
  </pm>

Tuned

Enable tuned service to set profile for kvm

GNOME Tweaks

Disable trackers

chmod -x /usr/lib/evolution/evolution-calendar-factory to disable evolution

TODO

  • 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

Sources

Redhat - Virtualiaztion Tuning and Optimization

Libvirt domain

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

GTK Display - GVT Blog VFIO tweaks QEMU hugepages hook

About

iGPU passthrough with GVT-G

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published