[SOLVED/TUTORAL] Event Device (evdev) Passthrough to a Windows Guest

I found a tutorial on Reddit which I have not seen being discussed around here that much (if at all). It explains how to make use of input event devices inside virtual guests using qemu and VirtIO drivers (optional).

I would like to know if you are familiar with it or if you even use it right now. I have followed the steps on Reddit and it works outstandingly well with one exception… My mouse, once grabbed, does not react on the left + right Ctrl shortcut which switches your devices between host and guest. It is stuck on my Windows guest and I can’t figure out what’s wrong.

I have tried two mice at this point, one wired and one wireless mouse. Maybe you guys have an idea.

My config (Updated):
  • Added myself it the group ‘input’
$ ls -l /dev/input/by-id/*-event-*
lrwxrwxrwx 1 root root 9  4. Dez 13:09 /dev/input/by-id/usb-Kingston_HyperX_Alloy_FPS_Mechanical_Gaming_Keyboard-event-kbd -> ../event4
lrwxrwxrwx 1 root root 9  4. Dez 13:09 /dev/input/by-id/usb-Kingston_HyperX_Alloy_FPS_Mechanical_Gaming_Keyboard-if01-event-mouse -> ../event5
lrwxrwxrwx 1 root root 9  4. Dez 13:14 /dev/input/by-id/usb-Logitech_USB_Receiver-if02-event-mouse -> ../event6

/etc/libvirt/qemu.conf:

cgroup_device_acl = [
    "/dev/input/by-id/usb-Kingston_HyperX_Alloy_FPS_Mechanical_Gaming_Keyboard-event-kbd",
    "/dev/input/by-id/usb-Kingston_HyperX_Alloy_FPS_Mechanical_Gaming_Keyboard-if01-event-mouse",
    "/dev/input/by-id/usb-Logitech_USB_Receiver-if02-event-mouse",
    "/dev/null", "/dev/full", "/dev/zero",
    "/dev/random", "/dev/urandom",
    "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
    "/dev/rtc","/dev/hpet", "/dev/vfio/vfio"
]

Libvirt guest config XML:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
...
  <devices>
    ...
    <input type='keyboard' bus='virtio'>
      <address type='pci' domain='0x0000' bus='0x0d' slot='0x00' function='0x0'/>
    </input>
    <input type='mouse' bus='virtio'>
      <address type='pci' domain='0x0000' bus='0x0f' slot='0x00' function='0x0'/>
    </input>
    ...
  </devices>
  ...
  <qemu:commandline>
    <qemu:arg value='-object'/>
    <qemu:arg value='input-linux,id=mouse1,evdev=/dev/input/by-id/usb-Logitech_USB_Receiver-if02-event-mouse'/>
    <qemu:arg value='-object'/>
    <qemu:arg value='input-linux,id=kbd1,evdev=/dev/input/by-id/usb-Kingston_HyperX_Alloy_FPS_Mechanical_Gaming_Keyboard-if01-event-mouse,grab_all=on,repeat=on'/>
    <qemu:arg value='-object'/>
    <qemu:arg value='input-linux,id=kbd2,evdev=/dev/input/by-id/usb-Kingston_HyperX_Alloy_FPS_Mechanical_Gaming_Keyboard-event-kbd,grab_all=on,repeat=on'/>
    <qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
    <qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
  </qemu:commandline>
</domain>

Isn’t the shortcut left alt+ctrl?

No, it’s hardcoded to left Ctrl + right Ctrl as far as I gathered. The keyboard does switch between host and guest as intended, only the mouse is stuck on guest-side.

Ah ok.
Any reason you want to passthrough the HIDs with custom settings?
Doesn’t the VM grab them nicely when you switch over from/to the host?
What VM manager are you using, or are you just using the terminal?

My host is running Arch Linux Kernel 4.14.3-1. I am using a PCI-Passthrough to run a GTX 1070 on a Windows guest. In the process I got rid of the entire spice components using a 2nd monitor. The packages I use are qemu, libvirt and virt-manager.

By default, I am using a USB 3.0 switch to use mouse and keyboard on both systems however the switch introduces coil whine when i turn on the lighting of my mechanical keyboard.
Another nuissance is that one of my USB controllers does not play nice with my audio interface which has to reside on host-side so i can hear both systems at the same time. That however means that i have to pass that controller with most of my ports to the guest, leaving the host with 1x USB-A and 1x USB-C. That’s really inconvenient.

There are no issues as far as I can tell except messages about unmapped keys in /var/log/libvirt/qemu/win10.log:

# These two keys are forward/backward buttons for page scrolling. They don't work with VirtIO drivers but do work under the standard PS/2 device
virtio_input_handle_event: unmapped button: 6 [extra]
virtio_input_handle_event: unmapped button: 5 [side]

# This entry appears whenever one of the other buttons (Left-MB, Right-MB, Middle-MB) is being pressed. However they work flawlessly on the guest.
virtio_input_handle_event: unmapped key: 0 [unmapped]
virtio_input_handle_event: unmapped key: 0 [unmapped]
virtio_input_handle_event: unmapped key: 0 [unmapped]
virtio_input_handle_event: unmapped key: 0 [unmapped]
...

I am using Virt-Manager for the basic stuff. For this to work I used virsh (a libvirt tool) to edit the config XML manually as you can see in OP.

I have found the solution thanks to the guys of the VFIO reddit.

In the libvirt config file both keyboard devices I addressed need to have the parameters grab_all=on,repeat=on added at the very end, not just one of them. I will update the OP accordingly.

I hope you guys can give it a try. In fact now its absolutely flawless so I can ditch the USB switch Ive been using up to this point.

do I have to have a keyboard passed through evdev in order to get my mouse to switch between hosts? Normally i just use my ps/2 keyboard through the spice protocol / looking glass.