Configuring libvirt for Looking Glass

This article assumes you already have a fully functional libvirt VM with PCI Passthrough working on a dedicated monitor. If you do not please ensure this is configured before you proceed.

Configuring the Virtual Machine for IVSHMEM

Add the following to the libvirt machine configuration by running "virsh edit VM" where VM is the name of your virtual machine.

<shmem name='looking-glass'>
  <model type='ivshmem-plain'/>
  <size unit='M'>32</size>
</shmem>

If libvirt doesn't like this syntax see below for the alternative syntax.

You will need to adjust the memory size to a value that is suitable for your desired maximum resolution using the following forumla:

width x height x 4 x 2 = total bytes
total bytes / 1024 / 1024 = total megabytes + 2

For example, for a resolution of 1920x1080

1920 x 1080 x 4 x 2 = 16,588,800 bytes
16,588,800 / 1024 / 1024 = 15.82 MB + 2 = 17.82

You must round this value up to the nearest power of two, which with the above example would be 32MB

It is suggested that you create the shared memory file before starting the VM with the appropriate permissions for your system, this only needs to be done once at boot time, for example (this is a sample script only, do not use this without altering it for your requirements):

touch /dev/shm/looking-glass
chown user:kvm /dev/shm/looking-glass
chmod 660 /dev/shm/looking-glass

Next step is to install the IVSHMEM driver in the guest


Alternative libvirt  syntax


Ensure the xml namespace is set on the top "domain" element:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

If you are running a version before commit 6a6e53f7280facc0cf47f2a0f43d12562c1ae5d7 (Alpha 9 or older) please skip ahead to the old instructions below:

Anywhere inside the domain element add the following for versions later then Alpha 9:

<qemu:commandline>
  <qemu:arg value='-device'/>
  <qemu:arg value='ivshmem-plain,memdev=ivshmem'/>
  <qemu:arg value='-object'/>
  <qemu:arg value='memory-backend-file,id=ivshmem,share=on,mem-path=/dev/shm/looking-glass,size=32M'/>
</qemu:commandline>

Next step is to install the IVSHMEM driver in the guest


Old Method for Alpha 9 or Older builds:

Anywhere inside the domain element add the following for versions later then Alpha 9:

<qemu:commandline>
  <qemu:arg value='-device'/>
  <qemu:arg value='ivshmem-doorbell,chardev=ivshmem,vectors=1'/>
  <qemu:arg value='-chardev'/>
  <qemu:arg value='socket,path=/tmp/ivshmem_socket,id=ivshmem'/>
</qemu:commandline>

Be sure to change the socket path to a value that suits you, it must be in a directory that is readable and writable by your current user and the user qemu is running as.

Starting the IVSHMEM server

Before the virtual machine can be started the IVSHMEM server must be started with enough memory for the maximum resolution you intend to use. To calculate the amount of memory required the formula is as follows:

width x height x 4 x 2 + 4224 = total bytes
total bytes / 1024 / 1024 = total megabytes

For example, for a resolution of 1920x1080

1920 x 1080 x 4 x 2 + 4224 = 16,593,024 bytes
16,593,024 / 1024 / 1024 = 15.82 MB

You must round this value up to the nearest integer, which in the above example would be 16MB

Now that you know how much memory you will require you can start the "ivshmem-server" application which comes with QEMU. You do not need to have any special privileges to launch the server, as long as you can read and write to the path specified in the libvirt virtual machine specification.

ivshmem-server -p /tmp/ivshmem.pid -S /tmp/ivshmem_socket -l 16M -n 8

Adjust the paths and memory amount as required. You can now start the VM.

Next step is to install the IVSHMEM driver in the guest