3. Quality of life tweaks - HikariKnight/vfio-setup-docs GitHub Wiki

Quality of life tweaks

Building LookingGlass

Note: This guide was originally intended to show how to compile the client for LookingGlass A12, as the instructions were not on the homepage last time I checked, they are now however so follow those!

What is LookingGlass?

The simple answer is that it lets you view the framebuffer from the GPU you are using in the virtual machine, so you get full hardware acceleration, however the Graphic Card still needs to be connected to a display or a “Ghost display emulator” so that the graphic card powers on with the virtual machine.
This way you do not need to constantly switch monitor output or have a dedicated monitor for the virtual machine.

LookingGlass has a built in SPICE client for seamless keyboard and mouse integration, however it is spotty in its reliability at best when it comes to the cursor. Personally I have found that using a software based KVM switch is a lot more reliable, or just passing through a dedicated keyboard and mouse for the virtual machine.

You can however press Scroll Lock and lock and unlock your cursor to the LookingGlass window, which in most cases solves a lot of the unreliability it has with the cursor, however it does not solve it for every application.

Please note that LookingGlass, as of the time of writing this is very early Alpha to Beta software, however it is far enough in development to be usable and is really good at what it does, with maybe some extra help in certain places!

  1. Turn off UAC in Windows as LookingGlass cannot display the Secure Desktop (the UAC prompt) currently (not sure if this is only for passed through NVidia cards as i lack an extra AMD card to test with).

  2. Follow the developers guide here: https://looking-glass.hostfission.com/quickstart and use the sable release (or the bleeding edge release if you dont care about stability, since things move so rapidly with this)

Note: It would also be nice if you can, to support or donate to the project, more details are on the homepage
https://looking-glass.hostfission.com/!

Software based KVM switch

This is a good alternative to LookingGlass alone or to use in along with LookingGlass by commenting out the DDC related lines of the scripts.

  1. In order to get this to work, you need more USB ports on your virtual machine.

    Open the Virtual Machine Manager and go to your virtual machines hardware details.

  2. Click on Controller USB 0 and change the model from USB 2 to USB 3 and apply the changes.

  3. Open the virtual machine configuration.

virsh edit yourvirtualmachinename
  1. Look for this line.
<controller type='usb' index='0' model='nec-xhci'>
  1. Add ports='10' to the end of the tag, the max amount of ports you can make are 10 from what I remember. The line should in the end look like this.
<controller type='usb' index='0' model='nec-xhci' ports='10'>
  1. Press CTRL+X to save and then continue forward.

  2. Follow the guide at https://github.com/rokups/rokups.github.io/blob/master/pages/full-software-kvm-switch.md

    My personal preference is to use the hotkey CTRL+ALT+SPACEBAR.
    You can find my personal hotkeyD program written in go at the link below, it will not trigger Anti-Cheat software to my knowledge compared to the AutoHotkey script used by rokups, and you can use it as a hotkey launcher for several programs.

hotkeyD: https://github.com/HikariKnight/hotkeyD

If you are using this with LookingGlass client, you might want to disable the spice client and be able to see the host cursor above the LookingGlass window by using the -s and -M parameters.

Note: This solution also works great with Barrier or Synergy if you have a license for it, personally I use Synergy1/Barrier as a server on the Windows VM and as a client on the Linux host so that it is only active when the keyboard and mouse are connected directly to the VM, this is due to keyboard layout issues when running Synergy as a server on Linux and due to it not working great in some games on the client side.

Sound through headphones/speakers or with LookingGlass

Sound through virt-viewer (easy)

The easiest solution I have found for this is to disable the spice client in the LookingGlass client using the -s parameter along with using the software KVM switch mentioned above and then use a script to open the virt-viewer for the virtual-machine and just minimize it or move it to a different workspace (or both!). For routing audio to PulseAudio instead (but may not work on some systems), check the ArchLinux Wiki.

  1. Make a new script in /usr/local/bin.
sudo nano /usr/local/bin/vm-sound
  1. Paste in the following script and replace yourvirtualmachinename with the name of your virtual machine.
#!/bin/bash
virt-viewer -w "yourvirtualmachinename"
  1. You can also use something like xdotool to move the window out of the way once it is launched, my full script looks something like this.
#!/bin/bash
virt-viewer -w "win10" &
sleep 10
xdotool windowminimize $(xdotool search --name "win10 \\(1\\) \\- Virt Viewer")
  1. Once you are done, save the file with CTRL+X and then run the below command to make it executable.
sudo chmod +x /usr/local/bin/vm-sound
  1. Now you can just run “vm-sound” whenever you want to get sound from the virtual machine, it is not perfect but it works.

Stream audio through Scream over the host-only network (easy, multiple users)

Note: The benefit with this over routing PulseAudio is that you can get sound from a VM that boots with the system, and you can also get better audio quality without crackles and low latency, this also works the same on qemu2.11 and qemu3.0+, which means you do not need to build qemu3.0+ if your repository does not have it.

  1. First in the windows VM you will need to download the scream server and install it from: https://github.com/duncanthrax/scream/releases

  2. To enable unicast. Open notepad and paste this in and save it as a .reg file and run it, change the IPv4 to point to your Linux host on your host-only network (default port is 4011).

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Scream\Options]
"UnicastIPv4"="10.10.10.1"
"UnicastPort"=dword:00000fab
  1. Set the windows default playback device to Scream (WDM) and reboot the VM.

  2. On the Linux host we will need to build the receiver, the commands below will install the build-essential tools, git and libpulse headers so we can compile the pulseaudio version of scream, it will then download the scream sources and compile scream-pulse.

sudo apt install build-essential libpulse-dev git
mkdir devel && cd devel
git clone https://github.com/duncanthrax/scream.git
cd ./scream/Receivers/pulseaudio
make
  1. Copy the built binary to /usr/local/bin
sudo cp -v ./scream-pulse /usr/local/bin/
  1. Now we just need to start the client (you can add this to your startup applications)

    for me the host-only interface for my host-only network is virbr1, yours might be different (it’s the one with the ip you wrote into the reg file earlier)

scream-pulse -u -p 4011 -i virbr1

Sound through PulseAudio (single user: easy, multiple users: insecure)

Another more seamless solution is to route audio through PulseAudio directly, removing virt-viewer completely from the equation. This method is a lot nicer and you do not need to keep a virt-viewer window open in the background.

I will write how to do this on a single user, as enabling this for multiple users requires adding more lines to apparmor for security (change 1000 to match other users IDs) and the simple way to make it work for multiple users is to make an anonymous socket which is insecure, as it will let other users listen into your audio while you are logged in, I will not show how to make the anonymous socket for that reason.

  1. Edit the qemu config for libvirt
sudo nano /etc/libvirt/qemu.conf
  1. Locate and uncomment the that starts with “user =” and replace the “yourusername” with your username.
user = “yourusername”
  1. Add our socket to apparmor
sudo nano /etc/apparmor.d/abstractions/libvirt-qemu
  1. Add the below part to the bottom of the file (replace 1000 with your user id number, you can find it by typing “id” into the terminal).

    Then press CTRL+X to save.

 # Pulseaudio access
 /run/user/1000/pulse/native rw,
  1. Now we need to edit our virtual machine to add the pulseaudio socket to the virtual machine.
virsh edit yourvirtualmachinename
  1. Replace <domain type='kvm'> with the below line if your virtual machine file starts with that.
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  1. Now scroll to the bottom and add the below lines between </devices> and </domain> and change 1000 to match the user ID of the user that will be using the virtual machine, if you already have a <qemu:commandline> section, only add the “<qemu:env” lines inside your existing <qemu:commandline> section.
<qemu:commandline>
  <qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
  <qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
</qemu:commandline>
  1. Press CTRL+X to save the file and reboot your system (or restart apparmor and pulseaudio, however I prefer a reboot).

Fixing audio crackle (moderate, takes time)

Note: To seriously save yourself time, check your version of Qemu installed before reading this!

Qemu 2.xx has audio crackling whenever you run anything CPU intensive, the severeness varies from task to task and in some cases can become unbearable. This is however fixed with a new timing system for the pulseaudio driver in Qemu3.0 and newer. The problem is that it is not available for Ubuntu 18.04 (as of writing) yet, so we will have to compile Qemu3.1 from source.

  1. Enable source repositories by ticking the “source code” checkbox in software-properties-gtk or by removing the # from the deb-src lines for the ubuntu repositories inside your sources.list then press CTRL+X to save the file.
sudo nano /etc/apt/sources.list
  1. Get the source dependencies to compile qemu.
sudo apt-get update && sudo apt-get build-dep qemu
  1. Get the source files for Qemu3.1.
mkdir ~/devel
cd ~/devel
wget https://download.qemu.org/qemu-3.1.0.tar.xz
tar -xf qemu-3.1.0.tar.xz
cd qemu-3.1.0
./configure --target-list=x86_64-softmmu --audio-drv-list=alsa,pa
  1. Next we will have to compile Qemu, however we do not want to run make install when we are done as we do not want to replace the system installed qemu as this version we are compiling would get replaced by a system update.

    Instead we will copy the binary and bios files to /usr/local so we can keep both the system qemu and our own qemu3.0+

make
sudo cp x86_64-softmmu/qemu-system-x86_64 /usr/local/bin/qemu3.1-system-x86_64
sudo cp -r pc-bios /usr/local/share/qemu
  1. Verify your qemu3.1 is working by typing in.
qemu3.1-system-x86_64 --version
  1. Now we need to add some new rules to apparmor to allow libvirt to access the binary.
sudo nano /etc/apparmor.d/abstractions/libvirt-qemu
  1. Add the lines below to the bottom of the file and press CTRL+X to save it.
# Allow access to qemu3.1
/usr/local/bin/qemu3.1-system-x86_64 rmix,
/usr/local/share/qemu/** r,
  1. Now we need to edit another apparmor file to allow libvirtd to execute qemu3.1
sudo nano /etc/apparmor.d/usr.sbin.libvirtd
  1. Locate where the rules for /bin/ and /sbin/ executables are and add the line below into that section and save with CTRL+X.
# Access to execute custom qemu3.1 binary
/usr/local/bin/qemu3.1-system-x86_64 PUx,
  1. Reload the apparmor rules.
sudo service apparmor reload
  1. Finally we need to edit our virtual machine to use one of the qemu3.0 specific chipset and tell libvirt to use qemu3.1 for this specific virtual machine.
virsh edit yourvirtualmachinename
  1. Locate the line that starts with “<type arch='x86_64' machine=” it should be somewhere inside the <os> section. Once you find it you will need to change your chipset to the 3.0 version (this example assumes youre using the default and most common i440fx chipset, but it also works on the q35 chipset) machine='pc-i440fx-XXXXXX' into machine='pc-i440fx-3.0' so it would look like something like this.
<type arch='x86_64' machine='pc-i440fx-3.0'>hvm</type>
  1. Now locate the start of the <devices> section and edit the <emulator> tag to point to our qemu3.1 binary. > The emulator tag should look like this when you are done.
<emulator>/usr/local/bin/qemu3.1-system-x86_64</emulator>
  1. Press CTRL+X to save and we will be done and you should now be able to enjoy almost completely crackle-free audio!
⚠️ **GitHub.com Fallback** ⚠️