Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dudeitssm/0d8498dcb492579b4106d57b3109bccc to your computer and use it in GitHub Desktop.
Save dudeitssm/0d8498dcb492579b4106d57b3109bccc to your computer and use it in GitHub Desktop.
LIbvirt (virt-manager) Evdev PS/2 Keyboard Passthrough

Libvirt (virt-manager) Evdev PS/2 Device Pass Through With SELINUX Enabled

Problem

I saw the following errors when passing a PS/2 keyboard through qemu arguments inside libvirt:

Error starting domain: internal error: qemu unexpectedly closed the monitor: 2022-06-13T00:07:02.581352Z qemu-kvm: -object input-linux,id=kbd1,evdev=/dev/input/by-path/platform-i8042-serio-0-event-kbd,grab_all=on,repeat=on: Could not open '/dev/input/by-path/platform-i8042-serio-0-event-kbd': No such file or directory
Error starting domain: internal error: process exited while connecting to monitor: 2022-06-13T00:07:02.581352Z qemu-kvm: Could not open '/dev/input/by-path/platform-i8042-serio-0-event-kbd': Permission denied

Specifications:

OS: Rocky Linux 8 (RHEL8/CentOS8)
Kernel: 4.18.0-372.9.1.el8.x86_64

Resolution

  1. Add your PS2 device in /etc/libvirt/qemu.conf. It seems we need to enable some legacy stuff that comes commented out by default.
PS2_KB_ID="/dev/input/by-path/platform-i8042-serio-0-event-kbd"

cat >> /etc/libvirt/qemu.conf << EOF
cgroup_device_acl = [
    "/dev/null", "/dev/full", "/dev/zero",
    "/dev/random", "/dev/urandom",
    "/dev/ptmx", "/dev/kvm",
    "${PS2_KB_ID}"
]
EOF
  1. Modify your VM's configuration to append a qemu argument containing your device ID. It is recommended to use the virt-xml tool for this:
DOMAIN_NAME="WINDOWS10_VM"
OBJECT_VALUE='input-linux,id=kbd1,evdev=/dev/input/by-path/platform-i8042-serio-0-event-kbd,grab_all=on,repeat=on'

virt-xml ${DOMAIN_NAME} --edit --confirm --qemu-commandline="-object ${OBJECT_VALUE}"

The output should look similar to:

# DOMAIN_NAME="WINDOWS10_VM"
# OBJECT_VALUE='input-linux,id=kbd1,evdev=/dev/input/by-path/platform-i8042-serio-0-event-kbd,grab_all=on,repeat=on'
# 
# virt-xml ${DOMAIN_NAME} --edit --confirm --qemu-commandline="-object ${OBJECT_VALUE}"
--- Original XML
+++ Altered XML
@@ -199,4 +199,8 @@
       <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
     </memballoon>
   </devices>
+  <qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
+    <qemu:arg value="-object"/>
+    <qemu:arg value="input-linux,id=kbd1,evdev=/dev/input/by-path/platform-i8042-serio-0-event-kbd,grab_all=on,repeat=on"/>
+  </qemu:commandline>
 </domain>

Define 'WINDOWS10_VM' with the changed XML? (y/n): y
Domain 'WINDOWS10_VM' defined successfully.

However, if you want to go the manual route, that also works. Use the above output for guidance.

  1. Add your libvirt running user (typically qemu) to the input group, so it can read/write /dev/input/ devices:
usermod -a qemu -G input
  1. Retry launching the VM. If you still get the same Permission denied error, it is likely due to SELINUX:
journalctl -t setroubleshoot
-- Logs begin at Sun 2022-06-12 20:43:38 EDT, end at Sun 2022-06-12 20:50:49 EDT. --
Jun 12 20:49:59 t3500 setroubleshoot[4756]: AnalyzeThread.run(): Cancel pending alarm
Jun 12 20:50:01 t3500 setroubleshoot[4756]: SELinux is preventing /usr/libexec/qemu-kvm from 'read, write' accesses on the chr_file event2. For complete SELinux messages run: sealert -l 5fce956f-a309-4619-a436-3>
Jun 12 20:50:01 t3500 setroubleshoot[4756]: SELinux is preventing /usr/libexec/qemu-kvm from 'read, write' accesses on the chr_file event2.
                                            
                                            *****  Plugin catchall (100. confidence) suggests   **************************
                                            
                                            If you believe that qemu-kvm should be allowed read write access on the event2 chr_file by default.
                                            Then you should report this as a bug.
                                            You can generate a local policy module to allow this access.
                                            Do
                                            allow this access for now by executing:
                                            # ausearch -c 'qemu-kvm' --raw | audit2allow -M my-qemukvm
                                            # semodule -X 300 -i my-qemukvm.pp

Do as it says:

ausearch -c 'qemu-kvm' --raw | audit2allow -M my-qemukvm
semodule -X 300 -i my-qemukvm.pp
rm my-qemukvm.pp my-qemukvm.te
  1. Retry launching the VM and it should succeed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment