VirGL is a driver that allows creating a virtual GPU within Virtual Machines that leverages host’s GPU without the need for passing it through (VFIO). Currently it’s mature enough to support window managers and maybe some really, really simple quake clones (I tried running Half Life 2… It did not work well). Currently it only supports Linux guests, although there was an experiment to get Windows guests working as well.
Hardware wise you need a GPU with DRM support. Intel iGPUs should work, so should most AMD cards. With nvidia cards you’re probably stuck on using the nouveau driver which is not ideal. Obviously, you also need a system capable of virtualisation.
Sadly the version of QEMU that comes with Ubuntu does not have VirGL support. Because of this, we’ll need to compile it with the necessary support.
Setting up QEMU is the easy part. In short -
sudo apt install build-essential libepoxy-dev libdrm-dev libgbm-dev libx11-dev libvirglrenderer-dev libpulse-dev libsdl2-dev python python-dev libpixman-1-dev build-essential.
wget http://download.qemu-project.org/qemu-2.12.0.tar.xz -O qemu.tar.xz(or whatever the latest version is at the time of reading).
mkdir qemu && tar -xf qemu.tar.xz -C qemu --strip-components=1 && cd qemu.
./configure --enable-sdl --with-sdlabi=2.0 --enable-opengl --enable-virglrenderer --enable-system --enable-modules --audio-drv-list=pa --target-list=x86_64-softmmu --enable-kvm.
After configure finishes it should output all of the features the new QEMU version will support. The ones that interest us are -
OpenGL dmabufs - all of them should be set to yes.
sudo make install.
This will install our newly compiled version to
/usr/local. You CAN install it over the distribution’s packages by setting the prefix for
configure, but personally I would refrain from doing so if only because you can accidentally mess up your existing virtual machines.
To install Libvirt you have two options - compile it manually or install it from distribution’s repositories. The first option has the added ‘benefit’ of being able to disable Apparmor which will block you from using Libvirt with a custom version of QEMU.
To simply install Libvirt without compiling it, just run
sudo apt install libvirt-bin and move on to the next section. Otherwise, if you choose to compile it yourself (which I don’t really recommend) then these commands should work -
sudo apt-get install git build-essential xsltproc libxml-xpath-perl libyajl-dev libdevmapper-dev libpciaccess-dev libnl-3-dev libnl-route-3-dev systemtap-sdt-dev uuid-dev libtool autoconf pkg-config libxml2 libxml2-utils autopoint python-dev libnuma-dev gettext gnutls-dev libxml2-dev numad librbd-dev build-essential.
wget https://libvirt.org/sources/libvirt-4.5.0.tar.xz -O libvirt.tar.xz(or find the latest version here).
mkdir libvirt && tar xf libvirt.tar.xz -C libvirt --strip-components=1 && cd libvirt.
./configure --with-qemu=yes --with-dtrace --with-numad --with-storage-rbd --disable-nls. If you want to compile without Apparmor support, append
--disable-apparmorto the command.
make -j$(nproc) && sudo make install.
This will install Libvirt to
If you compiled Libvirt without Apparmor support you can skip this section. Otherwise, you’ll need to manually add the executables to Apparmor access lists.
At the bottom of the file
/etc/apparmor.d/usr.sbin.libvirtd, just before the closing curly bracket (
}) add the following -
At the bottom of the
/etc/apparmor.d/abstractions/libvirt-qemu add the following (you might need to replace
/dev/dri/renderD128 with your own render device) -
You will also need to symlink the required libraries using
sudo ln -s /usr/lib/x86_64-linux-gnu/dri /usr/lib/dri because Libvirt (even the one from Ubuntu repositories) will not look into
x86_64-linux-gnu by default.
Now the fun part. First create a VM the way you usually would (i.e. using virt-install, using a web GUI like Kimchi etc.) and set it up. What you definitely want to set up is some sort of remote desktop software, like x2go, nomachine, one of the VNC server options (1, 2…), or even something like teamviewer. The reason for this is that enabling virgl will effectively kill QEMU’s SPICE socket - there’s no support for tcp sockets (it simply won’t let you start the VM), and I could not get file sockets to work with virgl enabled (the spice client connects, even shows you the name of the VM you’ve connected to, but there’s no video output).
After setting up your virtual machine, shut it down, and edit its Libvirt xml definition (
virsh edit <vm-name>). In it, you have to make the following changes (look below to see how the file should look like) -
<devices>, change (or add?) the
<emulator>used to your new qemu installation, i.e. -
- Set the
<graphics>type to spice and also enable the Opengl support, i.e. -
- Set the video adapter to VirtIO, i.e. -
Once done, save, let Libvirt validate it, and if it works, you can just start it. To test whether it works, connect to the VM and check if VirGL was enabled by running
dmesg | grep "virgl 3d acceleration enabled". If your dmesg contains this line, you’re good to go.
For reference -