OS Windows run on VM (ubuntu, libvirt, qemu-kvm). And I have PS/2 keyboard on host hardware. Is there any way to pass it to guest OS without lost of performance (maybe emulate USB keyboard with keys mapping from PS/2 keyboard). I tried to use Spice server (from libvirt GUI "Virtual Machine Manager"), but it gives very annoying delay when pressing keys.

2 Answers 2


First you must use virsh edit <vm-name> to modify the configuration XML, as you can't do this through the virt-manager GUI.

Check your top-level <domain> tag. It should look something like this:

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

If the type isn't kvm, you've boarded the wrong flight - start over with a new VM. If the xmlns:qemu attribute isn't there, add it.

If you already have a <qemu:commandline> section, then add these two lines inside it:

<qemu:arg value='-object'/>
<qemu:arg value='input-linux,id=kbd,evdev=/dev/input/eventN,grab_all=on,repeat=on'/>

If you don't, then create it right under the <domain> tag with those two tags inside it.

You will also need to create the keyboard device in the guest using the following XML, which you should add to the <devices> section:

<serial type='dev'>
<source path='/dev/input/eventN'/>
<target port='0'/>

The second qemu:arg and the source path defined here both have eventN defined. You will need to replace N with the input device number for your keyboard. Don't change the target port - just the source path.

My keyboard device is 2, but yours might be 0, or some other number. To find out which one yours is, do dmesg | grep input and look for your keyboard device. Mine says:

input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input2

You still want to use the path of /dev/input/eventN - this just lets you know what the right number is to use for N. If you're using X with evdev, which you probably are, you can also find this information in the X logfile. One caveat: Your device number might change if you reconfigure your host hardware.

Your keyboard will no longer be recognized by the host while you are using it in a guest. To control the host, you can:

  • Exit the guest, or
  • Attach another keyboard via USB, or
  • Log in via ssh, or
  • Use a serial console.

I got most of this information from this link:



I tried the steps from the other answer on Debian Bullseye and would like to update some instructions. I suggest to use journalctl -b and then search for input.*keyboard. My system had a longer uptime and dmesg did not show those lines anymore. I found:

kernel: input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/in>
systemd-logind[2716]: Watching system buttons on /dev/input/event0 (AT Translated Set 2 keyboard)

With this I knew my keyboard was using event0 at the moment an thus I could find it via ls -l /dev/input/by-path as /dev/input/by-path/platform-i8042-serio-0-event-kbd.

Since libvirt version 7.4.0, the domain XML supports <input type='evdev'>. I updated libvirt from bullseye-backports to get version 8. So, all I had to add to my VM XML was:

<input type="evdev">
  <source dev="/dev/input/by-path/platform-i8042-serio-0-event-kbd" grab="all" grabToggle="ctrl-ctrl" repeat="on"/>

Note the additional grabToggle="ctrl-ctrl" which allows to switch keyboard between guest and host by left ctrl + right ctrl.

I got this from Archlinux wiki. This also contains suggestions for further delay reduction by "switching from PS/2 to Virtio inputs", but I have not tried this.

The benefit of this approach is that you do not have to configure additional ACL/permissions for Qemu to use your keyboard. This caused problems on my side when I tried the approach with the qemu:commandline section.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .