Difference between revisions of "IGVT-g"

From NixOS Wiki
Jump to: navigation, search
m (rollback unauthorized mass edits)
Tag: Rollback
 
(19 intermediate revisions by 7 users not shown)
Line 1: Line 1:
Intel GVT-g is a full GPU virtualization solution with mediated pass-through which allows host and multiple guests to share same Intel integrated videocard. Guest gets a near-native graphics peformance.
+
Intel GVT-g is a technology that allows to "slice" an Intel GPU into virtualized GPUs that can be then passed into virtual machines.
  
Win7-32 / Win7-64 / Win8.1-64 /Win10-RS1-64 are validated.
+
Note that Intel GVT-g only supports Intel Broadwell (5th gen) to Comet Lake (10th gen), where in 10th gen support for IVGT-g was removed. For 11th gen, and 12th gen, there is SR-IOV coming up for virtualized GPUs, but that did not yet arrive in Linux mainline.
  
== Hardware Requirements ==
+
== Configuring GPU ==
  
For client platforms, 5th, 6th or 7th Generation Intel® Core Processor Graphics is required. For server platforms, E3_v4, E3_v5 or E3_v6 Xeon Processor Graphics is required.
+
First, enable iGVT-g with:
  
== Select VGPU devices ==
+
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 +
virtualisation.kvmgt.enable = true;
 +
</nowiki>}}
 +
... then rebuild and reboot.
 +
 
 +
 
 +
After rebooting, check if the driver was successfully loaded:
 +
 
 +
  $ ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
 +
 
 +
... if you get <code>No such file or directory</code>, it means you might be using an older CPU that needs an extra configuration option:
 +
 
 +
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 +
boot.extraModprobeConfig = "options i915 enable_guc=2";
 +
</nowiki>}}
 +
... then rebuild and reboot once again (unless that previous <code>ls</code> succeeded, in which case you don't have to modify that <code>extraModprobeConfig</code> at all).
  
Enable iGVT-g with {{file|/etc/nixos/configuration.nix|nix|<nowiki>
+
 
  virtualisation.kvmgt.enable = true;
+
Now, using <code>ls</code> you can list which variants your Intel GPU is able to virtualise:
</nowiki>}}
 
then rebuild and reboot. Choose virtual GPU
 
  
 
   $ ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
 
   $ ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
 
   i915-GVTg_V5_4/  i915-GVTg_V5_8/
 
   i915-GVTg_V5_4/  i915-GVTg_V5_8/
 +
 +
E.g.:
  
 
   $ cat /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_8/description  
 
   $ cat /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_8/description  
Line 24: Line 39:
 
   weight: 2
 
   weight: 2
  
Generate UUID
+
Find some variant that matches your expectations (resolution, memory size etc.), note down its name, generate a random UUID:
 +
 
 +
  # If you're using Nix Flakes:
 +
  $ nix shell nixpkgs#libossp_uuid -c uuid
 +
  a297db4a-f4c2-11e6-90f6-d3b88d6c9525
  
 +
  # If you're not using Nix Flakes:
 
   $ nix run nixpkgs.libossp_uuid -c uuid
 
   $ nix run nixpkgs.libossp_uuid -c uuid
 
   a297db4a-f4c2-11e6-90f6-d3b88d6c9525
 
   a297db4a-f4c2-11e6-90f6-d3b88d6c9525
  
== NixOS configuration ==
+
... and add that variant's name into your configuration:
  
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
  virtualisation.kvmgt.enable = true;  
+
virtualisation.kvmgt.enable = true;  
  virtualisation.kvmgt.vgpus = {
+
virtualisation.kvmgt.vgpus = {
    "i915-GVTg_V5_8" = {
+
  "i915-GVTg_V5_8" = {
      uuid = "a297db4a-f4c2-11e6-90f6-d3b88d6c9525";
+
    uuid = [ "a297db4a-f4c2-11e6-90f6-d3b88d6c9525" ];
    };
 
 
   };
 
   };
  environment.systemPackages = with pkgs; [
+
};
 +
 
 +
environment.systemPackages = with pkgs; [
 
   virtmanager
 
   virtmanager
  virt-viewer
+
];
  ];
+
 
  virtualisation.libvirtd.enable = true;
+
virtualisation.libvirtd.enable = true;
  users.extraUsers.user.extraGroups = [ "libvirtd" ];
+
users.extraUsers.user.extraGroups = [ "libvirtd" ];
 
</nowiki>}}
 
</nowiki>}}
  
== Configure KVM ==
+
Rebuild & voilá - your virtualized GPU is ready; now you just have to attach it to some virtual machine.
 +
 
 +
== Attaching GPU ==
  
 
=== Bare Qemu ===
 
=== Bare Qemu ===
Line 54: Line 77:
 
     -m 1G \
 
     -m 1G \
 
     -nodefaults \
 
     -nodefaults \
    -M graphics=off \
 
    -serial stdio \
 
 
     -display gtk,gl=on \
 
     -display gtk,gl=on \
     -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/'''a297db4a-f4c2-11e6-90f6-d3b88d6c9525''',display=on,x-igd-opregion=on
+
     -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/'''a297db4a-f4c2-11e6-90f6-d3b88d6c9525''',display=on,x-igd-opregion=on,driver=vfio-pci-nohotplug,ramfb=on,xres=1920,yres=1080
  
=== libvirtd ===
+
=== libvirt ===
  
If using virt-manager, create new or open existing VM.
+
If using virt-manager, create new or open existing VM. Change existing <code><graphics></code> and <code><video></code> sections.
  
 
sudo -E virsh edit win10
 
sudo -E virsh edit win10
<syntaxHighlight lang="xml" highlight="1,9">
+
<syntaxHighlight lang="xml" highlight="1,12">
 
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
 
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
 
   <devices>
 
   <devices>
Line 71: Line 92:
 
       <gl enable='yes'/>
 
       <gl enable='yes'/>
 
     </graphics>
 
     </graphics>
     <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci'>
+
    <video>
 +
      <model type='none'/>
 +
    </video>
 +
     <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on'>
 
       <source>
 
       <source>
 
         <address uuid='a297db4a-f4c2-11e6-90f6-d3b88d6c9525'/>
 
         <address uuid='a297db4a-f4c2-11e6-90f6-d3b88d6c9525'/>
Line 82: Line 106:
 
     <qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
 
     <qemu:arg value='device.hostdev0.x-igd-opregion=on'/>
 
     <qemu:arg value='-set'/>
 
     <qemu:arg value='-set'/>
     <qemu:arg value='device.hostdev0.display=on'/>
+
     <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.xres=1920'/>
 +
    <qemu:arg value='-set'/>
 +
    <qemu:arg value='device.hostdev0.yres=1080'/>
 +
    <qemu:env name="MESA_LOADER_DRIVER_OVERRIDE" value="i965"/>
 
   </qemu:commandline>
 
   </qemu:commandline>
 
</domain>
 
</domain>
 
</syntaxHighlight>
 
</syntaxHighlight>
Finally use sudo virt-viewer --attach win10
 
  
 
== FAQ ==
 
== FAQ ==
Line 92: Line 122:
 
* No video output
 
* No video output
  
** (libvirtd) Change main adapter type from QXL to say Cirrus
+
** use BIOS (SeaBIOS) machine, EFI (OVMF) is not supported. You may use the following workarounds https://wiki.archlinux.org/index.php/Intel_GVT-g#Using_DMA-BUF_with_UEFI/OVMF
 
 
** (libvirtd) Connect via `virt-viewer --attach` to see igvt-g display, virt-manager console will not show it
 
 
 
** use BIOS (SeaBIOS) machine, [https://lists.01.org/pipermail/igvt-g/2018-July/001431.html EFI (OVMF) is not supported]. As a workaround you may [https://gist.githubusercontent.com/gnidorah/2951b1f8bebeac899623fd67694ed47b/raw/99320ab33d30cc28b6813d630b6121e266032c30/gistfile1.txt create qcow boot image that is capable of booting EFI windows disk on BIOS machine]
 
  
 
** ensure that the recent Intel graphics driver is installed in the guest
 
** ensure that the recent Intel graphics driver is installed in the guest
Line 114: Line 140:
 
   1
 
   1
 
also check dmesg output for gvt related error, most likely there is not enough VRAM
 
also check dmesg output for gvt related error, most likely there is not enough VRAM
 
* There is no VGPU device that has resolution of my screen
 
 
** Use this program in guest https://www.monitortests.com/forum/Thread-Custom-Resolution-Utility-CRU to set resolution you need
 
  
 
* (libvirtd) VM stops immediately with no error other than "internal error: process exited while connecting to monitor"
 
* (libvirtd) VM stops immediately with no error other than "internal error: process exited while connecting to monitor"
Line 132: Line 154:
 
== Useful sources ==
 
== Useful sources ==
  
* [https://www.kraxel.org/blog/2018/04/vgpu-display-support-finally-merged-upstream/ <em>vgpu display support</em> on a contributor (kraxel)'s blog] - this guide misses info that Windows guest requires x-igd-opregion=on parameter and also that QXL may go into conflict
+
* https://www.kraxel.org/blog/2019/02/ramfb-display-in-qemu/ - Info about ramfb parameter
* https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide - obsoleted guide, but some parts are useful
+
* https://lists.01.org/hyperkitty/list/igvt-g@lists.01.org/thread/LAB74CANVVRKGPBJMHULMMUFX43LRH55/ - Info about x-igd-opregion parameter
* https://github.com/intel/gvt-linux/wiki/Dma_Buf_User_Guide - obsoleted guide, but some parts are useful
+
* https://www.kraxel.org/blog/2019/03/edid-support-for-qemu/ - Info about xres and yres parameters
* https://blog.bepbep.co/posts/gvt/ - How to get 60fps!
 
 
[[Category:Video]]
 
[[Category:Video]]
 
[[Category:Virtualization]]
 
[[Category:Virtualization]]

Latest revision as of 10:57, 6 April 2024

Intel GVT-g is a technology that allows to "slice" an Intel GPU into virtualized GPUs that can be then passed into virtual machines.

Note that Intel GVT-g only supports Intel Broadwell (5th gen) to Comet Lake (10th gen), where in 10th gen support for IVGT-g was removed. For 11th gen, and 12th gen, there is SR-IOV coming up for virtualized GPUs, but that did not yet arrive in Linux mainline.

Configuring GPU

First, enable iGVT-g with:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
virtualisation.kvmgt.enable = true;

... then rebuild and reboot.


After rebooting, check if the driver was successfully loaded:

 $ ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/

... if you get No such file or directory, it means you might be using an older CPU that needs an extra configuration option:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
boot.extraModprobeConfig = "options i915 enable_guc=2";

... then rebuild and reboot once again (unless that previous ls succeeded, in which case you don't have to modify that extraModprobeConfig at all).


Now, using ls you can list which variants your Intel GPU is able to virtualise:

 $ ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
 i915-GVTg_V5_4/  i915-GVTg_V5_8/

E.g.:

 $ cat /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_8/description 
 low_gm_size: 64MB
 high_gm_size: 384MB
 fence: 4
 resolution: 1024x768
 weight: 2

Find some variant that matches your expectations (resolution, memory size etc.), note down its name, generate a random UUID:

 # If you're using Nix Flakes:
 $ nix shell nixpkgs#libossp_uuid -c uuid
 a297db4a-f4c2-11e6-90f6-d3b88d6c9525
 # If you're not using Nix Flakes:
 $ nix run nixpkgs.libossp_uuid -c uuid
 a297db4a-f4c2-11e6-90f6-d3b88d6c9525

... and add that variant's name into your configuration:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
virtualisation.kvmgt.enable = true; 
virtualisation.kvmgt.vgpus = {
  "i915-GVTg_V5_8" = {
    uuid = [ "a297db4a-f4c2-11e6-90f6-d3b88d6c9525" ];
  };
};

environment.systemPackages = with pkgs; [
  virtmanager
];

virtualisation.libvirtd.enable = true;
users.extraUsers.user.extraGroups = [ "libvirtd" ];


Rebuild & voilá - your virtualized GPU is ready; now you just have to attach it to some virtual machine.

Attaching GPU

Bare Qemu

 qemu-system-x86_64 \
    -enable-kvm \
    -m 1G \
    -nodefaults \
    -display gtk,gl=on \
    -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/a297db4a-f4c2-11e6-90f6-d3b88d6c9525,display=on,x-igd-opregion=on,driver=vfio-pci-nohotplug,ramfb=on,xres=1920,yres=1080

libvirt

If using virt-manager, create new or open existing VM. Change existing <graphics> and <video> sections.

sudo -E virsh edit win10

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <devices>
    <graphics type='spice'>
      <listen type='none'/>
      <gl enable='yes'/>
    </graphics>
    <video>
      <model type='none'/>
    </video>
    <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on'>
      <source>
        <address uuid='a297db4a-f4c2-11e6-90f6-d3b88d6c9525'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </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.ramfb=on'/>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.driver=vfio-pci-nohotplug'/>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.xres=1920'/>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.hostdev0.yres=1080'/>
    <qemu:env name="MESA_LOADER_DRIVER_OVERRIDE" value="i965"/>
  </qemu:commandline>
</domain>

FAQ

  • No video output
    • ensure that the recent Intel graphics driver is installed in the guest
  • (libvirtd) "Element domain has extra content: qemu:commandline" error after editing via virsh
    • you forgot to add xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'
  • (libvirtd) "no drm render node available" error in virt-manager
    • in virt-manager change SPICE display render node from auto to available one
  • "write_loop: No space left on device" error when creating mdev device
    • check whether available instances are left
 $ cat /sys/bus/pci/devices/0000\:00\:02.0/mdev_supported_types/i915-GVTg_V5_4/available_instances 
 1

also check dmesg output for gvt related error, most likely there is not enough VRAM

  • (libvirtd) VM stops immediately with no error other than "internal error: process exited while connecting to monitor"

Try disabling seccomp sandboxing in qemu like so:

  virtualisation.libvirtd = {
    qemuVerbatimConfig = ''
      seccomp_sandbox = 0
    '';
  };

Useful sources