Tag Archives: virgl

Using virtio-gpu with libvirt and spice

It’s been a while since the last virtio-gpu status report. So, here we go with an update.

I gave a talk about qemu graphics at KVM Forum 2016 in Toronto, covering (among other things) virtio-gpu. Here are the slides. I’ll go summarize the important stuff for those who want to play with it below. The new blog picture above is the Toronto skyline btw.

First the good news: Almost everything needed is upstream meanwhile, so using virtio-gpu (with virgl aka opengl acceleration) is alot easier these days. Fedora 24 supports it out-of-the-box for both host and guest.

Requirements for the guest:

  • linux kernel 4.4 (version 4.2 without opengl)
  • mesa 11.1
  • xorg server 1.19, or 1.18 with commit "5627708 dri2: add virtio-gpu pci ids" backported

Requirements for the host:

  • qemu 2.6
  • virglrenderer
  • spice server 0.13.2 (development release)
  • spice-gtk 0.32 (used by virt-viewer & friends)
    Note that 0.32 got a new shared library major version, therefore the tools using this must be compiled against that version.
  • mesa 10.6
  • libepoxy 1.3.1

The libvirt domain config snippet:

<graphics type='spice'>
  <listen type='none'/>
  <gl enable='yes'/>
</graphics>
<video>
  <model type='virtio'/>
</video>

And the final important bit is that spice needs a unix socket connection for opengl to work, and you’ll get it by attaching the viewer to qemu this way:

virt-viewer --attach $domain

If everything went fine you should see this in the guests linux kernel log:

root@fedora ~# dmesg | grep '\[drm\]'
[drm] Initialized drm 1.1.0 20060810
[drm] pci: virtio-vga detected
[drm] virgl 3d acceleration enabled
[drm] virtio vbuffers: 272 bufs, 192B each, 51kB total.
[drm] number of scanouts: 1
[drm] number of cap sets: 1
[drm] cap set 0: id 1, max-version 1, max-size 308
[drm] Initialized virtio_gpu 0.0.1 0 on minor 0

And glxinfo should print something like this:

root@fedora ~# glxinfo | grep ^OpenGL
OpenGL vendor string: Red Hat
OpenGL renderer string: Gallium 0.4 on virgl
OpenGL core profile version string: 3.3 (Core Profile) Mesa 12.0.2
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 12.0.2
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 12.0.2
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00
OpenGL ES profile extensions:

latest updates from virtio-gpu department

It’s been a while since the last virtio-cpu status report. qemu 2.6 release is just around the corner, time for a writeup about what is coming.

virgl support was added to qemu 2.5 already. It was supported only by the SDL2 and gtk UIs. Which is a nice start, but has the drawback that qemu needs direct access to your display. You can’t logout from your desktop session without also killing the virtual machine.

qemu 2.6 features headless opengl support and spice integration. qemu will use render nodes, render the guest display into dma-bufs, and pass on those dma-bufs to spice-client for display (if connected). Works for local display only for now, i.e. spice will simply display the dma-bufs. Long-term plan (after the spice video support overhaul currently in progress is merged) is to also support hardware-assisted video encoding for a remote display.

If you want play with this you need:

  • latest spice-gtk version (0.31)
  • latest spice-server development release (0.13.1)
  • virglrenderer (packages should start showing up in distros now).

If you are running fedora or rhel7 you can use my copr repo.
And of course you need latest qemu (2.6 release candidate or final release once out) too.

OpenGL support is off by default in qemu, you have to enable it manually by appending gl=on to the -spice options. libvirt 1.3.0 and newer has support for that in the domain xml. The spice client must be attached (virt-viewer –attach) using unix sockets because they are used to pass the dma-bug file descriptors.

Have fun!

virtio-gpu and libvirt

libvirt has no support for virtio-vga yet. There is a bug for virtio-vga support in libvirt. But for the time being we need to play some tricks. Luckily libvirt has some special xml syntax to pass command line options to qemu. So here we go:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  [ ... ]
  <device>
    [ ... ]
    <video>
      <model type='cirrus' vram='16384' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    [ ... ]
  </devices>
  <qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.video0.driver=virtio-vga'/>
  </qemu:commandline>
</domain>

The idea is to tell libvirt we wanna have a cirrus vga. That one has no config options, thats why it works best for our purposes. Then use the -set switch to change the emulation driver from cirrus to virtio-vga. video0 is the id libvirt assigns to the (first and only) video device.

Next level is turning on virgl & opengl support. Initially sdl and gtk user interfaces will be supported (qemu 2.5 most likely). Spice will follow later. So lets pick gtk. Here we go:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  [ ... ]
  <device>
    [ ... ]
    <graphics type='sdl' display=':0' xauth='/path/to/.Xauthority'/>
    <video>
      <model type='cirrus' vram='16384' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    [ ... ]
  </devices>
  <qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.video0.driver=virtio-vga'/>
    <qemu:arg value='-display'/>
    <qemu:arg value='gtk,gl=on'/>
  </qemu:commandline>
</domain>

Simliar approach: We ask libvirt for sdl support. Picking that one because libvirt will take care to pass xauth info to qemu so it gets access to the X11 display. Then use the -display switch to override the libvirt display configuration with gtk, and turn on opengl.

One final remark: On modern linux systems xauth info is stored in /run/gdm/auth-for-$USER-$RANDOM/database instead of $HOME/.Xauthority. I have a little script to copy the xauth info to a fixed place and also make it readable so libvirt can access it:

#!/bin/sh
if test "$XAUTHORITY" != "$HOME/.Xauthority"; then
    xauth extract "$HOME/.Xauthority" "$DISPLAY"
    chmod +r $HOME/.Xauthority
fi

Note that making .Xauthority world-readable effectively gives every user on your machine access to your X11 display. On your private laptop where you are the only user that should be ok, but on a shared machine you probably want do something more secure instead.

virtio-gpu on the way upstream

We are making progress, time for the next status report …

virtio-gpu, 2d mode

It’s on the way upstream, both guest and host side. The qemu code landed in git master already and will be shipped with the upcoming 2.4 release. The linux kms driver is in drm-next right now and will most likely land upstream in the 4.2 merge window.

virtio-gpu, 3d mode

With 2d mode being almost completed now the focus shifts to put 3d/virgl into shape.

The qemu code is in a new virgl branch now, the vga and ui bits are no longer separated.

Current state: SDL2 display is working. egl display (headless, see below) is working.

TODO list: Make gtk diplay (egl mode) work. Add support for native opengl (available in 3.16+, needed to run on wayland) to gtk display. Add spice support.

Building qemu with virgl:
You need virglrenderer. Copr has packages. If you want try egl display too you need pretty cutting edge mesa and libepoxy packages, for dma-buf export and import support. Fedora 22 will do for mesa. For libepoxy you need the rawhide/F23 version.

Linux guest bits for virgl:
The virtio-gpu branch in my linux repo has the kernel bits you need. The Copr repos have a “mesa.git” package which you need to install. This isn’t full mesa, only the guest driver for virtio-gpu. I suggest to use Fedora 22 as guest as I’m usually testing with F22 too.

You might need to put selinux (at the host) into permissive mode when playing with this. svirt doesn’t allow qemu access the gpu.

headless egl display

In this mode qemu doesn’t need access to your X11 (or wayland) display. It’ll open a drm render node instead and use that for opengl operations. The guest display is rendered into a dma-buf. A simple standalone app can connect to qemu, get access to the dma-bufs via file descriptor passing and blit the dma-buf to your screen.

Start qemu: qemu-system-x86_64 -display egl -name $name
Start viewer: qemu-eglview $name

The viewer is proof-of-concept for the dma-buf passing and it is pretty simple. No pointer shape support. No relative pointer support, so a tablet device is mandatory for the guest if you want a working pointer.

Not sure yet how the long-term future will look like for qemu-eglview. Right now it is a useful hacking and testing tool. But spice will some day operate in a very simliar way and additionally provide all the extra goodies spice has to offer (sound, usb, smartcard, webdav, …), so it probably isn’t that useful to turn it into a full-blown viewer app …

virtio-gpu and virgl status update

Just received a email asking where we are in terms of virgl support in qemu, partly because the links from last years kvm talk are outdated meanwhile. I suspect there might be more folks wondering, so it is probably a good idea to write up an update in public. So, here we go with the news …

virglrenderer isn’t a branch in Dave’s mesa repo any more, it got factored out into its own git repo.

The mesa guest driver still is in Dave’s mesa repo (branch virgl-mesa-driver).

The xorg guest driver is not needed any more because xorg can do 2d acceleration via opengl/mesa now.

The guest kernel driver is in my virtio-gpu branch.

The qemu bits are splitted over two branches at the moment: The sdl2 and opengl bits are in my sdl branch, whereas the virtio-gpu bits are in the vga branch. In theory making things work should be as easy as merging these two branches. I didn’t test this for a while though as I’m busy bringing the first batch of virtio-gpu patches (with 2d support only) into shape for upstream merging.

Upstream merge is stalled atm because the virtio-gpu patches depend on virtio 1.0 support, which in turn is blocked by qemu being in freeze for the 2.3 release right now. Things should start moving forward very soon though, once qemu 2.3 is released the master branch will be opened for 2.4 development.