2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer
12 * in this position and unchanged.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * virtio input device emulation.
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
37 #include <sys/param.h>
38 #ifndef WITHOUT_CAPSICUM
39 #include <sys/capsicum.h>
41 #include <capsicum_helpers.h>
43 #include <sys/ioctl.h>
44 #include <sys/linker_set.h>
47 #include <dev/evdev/input.h>
68 #define VTINPUT_RINGSZ 64
70 #define VTINPUT_MAX_PKT_LEN 10
75 #define VTINPUT_EVENTQ 0
76 #define VTINPUT_STATUSQ 1
78 #define VTINPUT_MAXQ 2
80 static int pci_vtinput_debug;
81 #define DPRINTF(params) \
82 if (pci_vtinput_debug) \
84 #define WPRINTF(params) PRINTLN params
86 enum vtinput_config_select {
87 VTINPUT_CFG_UNSET = 0x00,
88 VTINPUT_CFG_ID_NAME = 0x01,
89 VTINPUT_CFG_ID_SERIAL = 0x02,
90 VTINPUT_CFG_ID_DEVIDS = 0x03,
91 VTINPUT_CFG_PROP_BITS = 0x10,
92 VTINPUT_CFG_EV_BITS = 0x11,
93 VTINPUT_CFG_ABS_INFO = 0x12
96 struct vtinput_absinfo {
104 struct vtinput_devids {
111 struct vtinput_config {
119 struct vtinput_absinfo abs;
120 struct vtinput_devids ids;
124 struct vtinput_event {
130 struct vtinput_event_elem {
131 struct vtinput_event event;
136 struct vtinput_eventqueue {
137 struct vtinput_event_elem *events;
145 struct pci_vtinput_softc {
146 struct virtio_softc vsc_vs;
147 struct vqueue_info vsc_queues[VTINPUT_MAXQ];
148 pthread_mutex_t vsc_mtx;
149 const char *vsc_evdev;
151 struct vtinput_config vsc_config;
152 int vsc_config_valid;
153 struct mevent *vsc_evp;
154 struct vtinput_eventqueue vsc_eventqueue;
157 static void pci_vtinput_reset(void *);
158 static int pci_vtinput_cfgread(void *, int, int, uint32_t *);
159 static int pci_vtinput_cfgwrite(void *, int, int, uint32_t);
161 static struct virtio_consts vtinput_vi_consts = {
162 "vtinput", /* our name */
163 VTINPUT_MAXQ, /* we support 1 virtqueue */
164 sizeof(struct vtinput_config), /* config reg size */
165 pci_vtinput_reset, /* reset */
166 NULL, /* device-wide qnotify -- not used */
167 pci_vtinput_cfgread, /* read virtio config */
168 pci_vtinput_cfgwrite, /* write virtio config */
169 NULL, /* apply negotiated features */
170 0, /* our capabilities */
174 pci_vtinput_reset(void *vsc)
176 struct pci_vtinput_softc *sc = vsc;
178 DPRINTF(("%s: device reset requested", __func__));
179 vi_reset_dev(&sc->vsc_vs);
183 pci_vtinput_notify_eventq(void *vsc, struct vqueue_info *vq)
185 DPRINTF(("%s", __func__));
189 pci_vtinput_notify_statusq(void *vsc, struct vqueue_info *vq)
191 struct pci_vtinput_softc *sc = vsc;
193 while (vq_has_descs(vq)) {
194 /* get descriptor chain */
197 const int n = vq_getchain(vq, &iov, 1, &req);
199 WPRINTF(("%s: invalid descriptor: %d", __func__, n));
204 struct vtinput_event event;
205 memcpy(&event, iov.iov_base, sizeof(event));
208 * on multi touch devices:
209 * - host send EV_MSC to guest
210 * - guest sends EV_MSC back to host
211 * - host writes EV_MSC to evdev
212 * - evdev saves EV_MSC in it's event buffer
213 * - host receives an extra EV_MSC by reading the evdev event
215 * - frames become larger and larger
216 * avoid endless loops by ignoring EV_MSC
218 if (event.type == EV_MSC) {
219 vq_relchain(vq, req.idx, sizeof(event));
223 /* send event to evdev */
224 struct input_event host_event;
225 host_event.type = event.type;
226 host_event.code = event.code;
227 host_event.value = event.value;
228 if (gettimeofday(&host_event.time, NULL) != 0) {
229 WPRINTF(("%s: failed gettimeofday", __func__));
231 if (write(sc->vsc_fd, &host_event, sizeof(host_event)) == -1) {
232 WPRINTF(("%s: failed to write host_event", __func__));
235 vq_relchain(vq, req.idx, sizeof(event));
241 pci_vtinput_get_bitmap(struct pci_vtinput_softc *sc, int cmd, int count)
243 if (count <= 0 || !sc) {
248 memset(sc->vsc_config.u.bitmap, 0, sizeof(sc->vsc_config.u.bitmap));
249 if (ioctl(sc->vsc_fd, cmd, sc->vsc_config.u.bitmap) < 0) {
253 /* get number of set bytes in bitmap */
254 for (int i = count - 1; i >= 0; i--) {
255 if (sc->vsc_config.u.bitmap[i]) {
264 pci_vtinput_read_config_id_name(struct pci_vtinput_softc *sc)
267 if (ioctl(sc->vsc_fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
271 memcpy(sc->vsc_config.u.string, name, sizeof(name));
272 sc->vsc_config.size = strnlen(name, sizeof(name));
278 pci_vtinput_read_config_id_serial(struct pci_vtinput_softc *sc)
280 /* serial isn't supported */
281 sc->vsc_config.size = 0;
287 pci_vtinput_read_config_id_devids(struct pci_vtinput_softc *sc)
289 struct input_id devids;
290 if (ioctl(sc->vsc_fd, EVIOCGID, &devids)) {
294 sc->vsc_config.u.ids.bustype = devids.bustype;
295 sc->vsc_config.u.ids.vendor = devids.vendor;
296 sc->vsc_config.u.ids.product = devids.product;
297 sc->vsc_config.u.ids.version = devids.version;
298 sc->vsc_config.size = sizeof(struct vtinput_devids);
304 pci_vtinput_read_config_prop_bits(struct pci_vtinput_softc *sc)
307 * Evdev bitmap countains 1 bit per count. Additionally evdev bitmaps
308 * are arrays of longs instead of chars. Calculate how many longs are
309 * required for evdev bitmap. Multiply that with sizeof(long) to get the
310 * number of elements.
312 const int count = howmany(INPUT_PROP_CNT, sizeof(long) * 8) *
314 const unsigned int cmd = EVIOCGPROP(count);
315 const int size = pci_vtinput_get_bitmap(sc, cmd, count);
320 sc->vsc_config.size = size;
326 pci_vtinput_read_config_ev_bits(struct pci_vtinput_softc *sc, uint8_t type)
354 * Evdev bitmap countains 1 bit per count. Additionally evdev bitmaps
355 * are arrays of longs instead of chars. Calculate how many longs are
356 * required for evdev bitmap. Multiply that with sizeof(long) to get the
357 * number of elements.
359 count = howmany(count, sizeof(long) * 8) * sizeof(long);
360 const unsigned int cmd = EVIOCGBIT(sc->vsc_config.subsel, count);
361 const int size = pci_vtinput_get_bitmap(sc, cmd, count);
366 sc->vsc_config.size = size;
372 pci_vtinput_read_config_abs_info(struct pci_vtinput_softc *sc)
374 /* check if evdev has EV_ABS */
375 if (!pci_vtinput_read_config_ev_bits(sc, EV_ABS)) {
379 /* get abs information */
380 struct input_absinfo abs;
381 if (ioctl(sc->vsc_fd, EVIOCGABS(sc->vsc_config.subsel), &abs) < 0) {
385 /* save abs information */
386 sc->vsc_config.u.abs.min = abs.minimum;
387 sc->vsc_config.u.abs.max = abs.maximum;
388 sc->vsc_config.u.abs.fuzz = abs.fuzz;
389 sc->vsc_config.u.abs.flat = abs.flat;
390 sc->vsc_config.u.abs.res = abs.resolution;
391 sc->vsc_config.size = sizeof(struct vtinput_absinfo);
397 pci_vtinput_read_config(struct pci_vtinput_softc *sc)
399 switch (sc->vsc_config.select) {
400 case VTINPUT_CFG_UNSET:
402 case VTINPUT_CFG_ID_NAME:
403 return pci_vtinput_read_config_id_name(sc);
404 case VTINPUT_CFG_ID_SERIAL:
405 return pci_vtinput_read_config_id_serial(sc);
406 case VTINPUT_CFG_ID_DEVIDS:
407 return pci_vtinput_read_config_id_devids(sc);
408 case VTINPUT_CFG_PROP_BITS:
409 return pci_vtinput_read_config_prop_bits(sc);
410 case VTINPUT_CFG_EV_BITS:
411 return pci_vtinput_read_config_ev_bits(
412 sc, sc->vsc_config.subsel);
413 case VTINPUT_CFG_ABS_INFO:
414 return pci_vtinput_read_config_abs_info(sc);
421 pci_vtinput_cfgread(void *vsc, int offset, int size, uint32_t *retval)
423 struct pci_vtinput_softc *sc = vsc;
425 /* check for valid offset and size */
426 if (offset + size > sizeof(struct vtinput_config)) {
427 WPRINTF(("%s: read to invalid offset/size %d/%d", __func__,
429 memset(retval, 0, size);
433 /* read new config values, if select and subsel changed. */
434 if (!sc->vsc_config_valid) {
435 if (pci_vtinput_read_config(sc) != 0) {
436 DPRINTF(("%s: could not read config %d/%d", __func__,
437 sc->vsc_config.select, sc->vsc_config.subsel));
438 memset(retval, 0, size);
441 sc->vsc_config_valid = 1;
444 uint8_t *ptr = (uint8_t *)&sc->vsc_config;
445 memcpy(retval, ptr + offset, size);
451 pci_vtinput_cfgwrite(void *vsc, int offset, int size, uint32_t value)
453 struct pci_vtinput_softc *sc = vsc;
455 /* guest can only write to select and subsel fields */
456 if (offset + size > 2) {
457 WPRINTF(("%s: write to readonly reg %d", __func__, offset));
461 /* copy value into config */
462 uint8_t *ptr = (uint8_t *)&sc->vsc_config;
463 memcpy(ptr + offset, &value, size);
465 /* select/subsel changed, query new config on next cfgread */
466 sc->vsc_config_valid = 0;
472 vtinput_eventqueue_add_event(
473 struct vtinput_eventqueue *queue, struct input_event *e)
475 /* check if queue is full */
476 if (queue->idx >= queue->size) {
477 /* alloc new elements for queue */
478 const uint32_t newSize = queue->idx;
479 const void *newPtr = realloc(queue->events,
480 queue->size * sizeof(struct vtinput_event_elem));
481 if (newPtr == NULL) {
482 WPRINTF(("%s: realloc memory for eventqueue failed!",
486 /* save new size and eventqueue */
487 queue->events = (struct vtinput_event_elem *)newPtr;
488 queue->size = newSize;
492 struct vtinput_event *event = &queue->events[queue->idx].event;
493 event->type = e->type;
494 event->code = e->code;
495 event->value = e->value;
502 vtinput_eventqueue_clear(struct vtinput_eventqueue *queue)
504 /* just reset index to clear queue */
509 vtinput_eventqueue_send_events(
510 struct vtinput_eventqueue *queue, struct vqueue_info *vq)
513 * First iteration through eventqueue:
514 * Get descriptor chains.
516 for (uint32_t i = 0; i < queue->idx; ++i) {
518 if (!vq_has_descs(vq)) {
520 * We don't have enough descriptors for all events.
521 * Return chains back to guest.
525 "%s: not enough available descriptors, dropping %d events",
526 __func__, queue->idx));
530 /* get descriptor chain */
533 const int n = vq_getchain(vq, &iov, 1, &req);
535 WPRINTF(("%s: invalid descriptor: %d", __func__, n));
540 ("%s: invalid number of descriptors in chain: %d",
542 /* release invalid chain */
543 vq_relchain(vq, req.idx, 0);
546 if (iov.iov_len < sizeof(struct vtinput_event)) {
547 WPRINTF(("%s: invalid descriptor length: %lu", __func__,
549 /* release invalid chain */
550 vq_relchain(vq, req.idx, 0);
554 /* save descriptor */
555 queue->events[i].iov = iov;
556 queue->events[i].idx = req.idx;
560 * Second iteration through eventqueue:
561 * Send events to guest by releasing chains
563 for (uint32_t i = 0; i < queue->idx; ++i) {
564 struct vtinput_event_elem event = queue->events[i];
565 memcpy(event.iov.iov_base, &event.event,
566 sizeof(struct vtinput_event));
567 vq_relchain(vq, event.idx, sizeof(struct vtinput_event));
570 /* clear queue and send interrupt to guest */
571 vtinput_eventqueue_clear(queue);
578 vtinput_read_event_from_host(int fd, struct input_event *event)
580 const int len = read(fd, event, sizeof(struct input_event));
581 if (len != sizeof(struct input_event)) {
582 if (len == -1 && errno != EAGAIN) {
583 WPRINTF(("%s: event read failed! len = %d, errno = %d",
584 __func__, len, errno));
587 /* host doesn't have more events for us */
595 vtinput_read_event(int fd __attribute((unused)),
596 enum ev_type t __attribute__((unused)), void *arg __attribute__((unused)))
598 struct pci_vtinput_softc *sc = arg;
600 /* skip if driver isn't ready */
601 if (!(sc->vsc_vs.vs_status & VIRTIO_CONFIG_STATUS_DRIVER_OK))
604 /* read all events from host */
605 struct input_event event;
606 while (vtinput_read_event_from_host(sc->vsc_fd, &event) == 0) {
607 /* add events to our queue */
608 vtinput_eventqueue_add_event(&sc->vsc_eventqueue, &event);
610 /* only send events to guest on EV_SYN or SYN_REPORT */
611 if (event.type != EV_SYN || event.type != SYN_REPORT) {
615 /* send host events to guest */
616 vtinput_eventqueue_send_events(
617 &sc->vsc_eventqueue, &sc->vsc_queues[VTINPUT_EVENTQ]);
622 pci_vtinput_legacy_config(nvlist_t *nvl, const char *opts)
629 * virtio-input,/dev/input/eventX
631 char *cp = strchr(opts, ',');
633 set_config_value_node(nvl, "path", opts);
636 char *path = strndup(opts, cp - opts);
637 set_config_value_node(nvl, "path", path);
640 return (pci_parse_legacy_config(nvl, cp + 1));
644 pci_vtinput_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
646 struct pci_vtinput_softc *sc;
650 * Else it's possible to access it uninitialized by jumping to failed.
652 pthread_mutexattr_t mtx_attr = NULL;
654 sc = calloc(1, sizeof(struct pci_vtinput_softc));
656 sc->vsc_evdev = get_config_value_node(nvl, "path");
657 if (sc->vsc_evdev == NULL) {
658 WPRINTF(("%s: missing required path config value", __func__));
663 * open evdev by using non blocking I/O:
664 * read from /dev/input/eventX would block our thread otherwise
666 sc->vsc_fd = open(sc->vsc_evdev, O_RDWR | O_NONBLOCK);
667 if (sc->vsc_fd < 0) {
668 WPRINTF(("%s: failed to open %s", __func__, sc->vsc_evdev));
672 /* check if evdev is really a evdev */
674 int error = ioctl(sc->vsc_fd, EVIOCGVERSION, &evversion);
676 WPRINTF(("%s: %s is no evdev", __func__, sc->vsc_evdev));
680 /* gain exclusive access to evdev */
681 error = ioctl(sc->vsc_fd, EVIOCGRAB, 1);
683 WPRINTF(("%s: failed to grab %s", __func__, sc->vsc_evdev));
687 if (pthread_mutexattr_init(&mtx_attr)) {
688 WPRINTF(("%s: init mutexattr failed", __func__));
691 if (pthread_mutexattr_settype(&mtx_attr, PTHREAD_MUTEX_RECURSIVE)) {
692 WPRINTF(("%s: settype mutexattr failed", __func__));
695 if (pthread_mutex_init(&sc->vsc_mtx, &mtx_attr)) {
696 WPRINTF(("%s: init mutex failed", __func__));
701 sc->vsc_eventqueue.idx = 0;
702 sc->vsc_eventqueue.size = VTINPUT_MAX_PKT_LEN;
703 sc->vsc_eventqueue.events = calloc(
704 sc->vsc_eventqueue.size, sizeof(struct vtinput_event_elem));
705 sc->vsc_config_valid = 0;
706 if (sc->vsc_eventqueue.events == NULL) {
707 WPRINTF(("%s: failed to alloc eventqueue", __func__));
711 /* register event handler */
712 sc->vsc_evp = mevent_add(sc->vsc_fd, EVF_READ, vtinput_read_event, sc);
713 if (sc->vsc_evp == NULL) {
714 WPRINTF(("%s: could not register mevent", __func__));
718 #ifndef WITHOUT_CAPSICUM
720 cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE);
721 if (caph_rights_limit(sc->vsc_fd, &rights) == -1) {
722 errx(EX_OSERR, "Unable to apply rights for sandbox");
726 /* link virtio to softc */
728 &sc->vsc_vs, &vtinput_vi_consts, sc, pi, sc->vsc_queues);
729 sc->vsc_vs.vs_mtx = &sc->vsc_mtx;
731 /* init virtio queues */
732 sc->vsc_queues[VTINPUT_EVENTQ].vq_qsize = VTINPUT_RINGSZ;
733 sc->vsc_queues[VTINPUT_EVENTQ].vq_notify = pci_vtinput_notify_eventq;
734 sc->vsc_queues[VTINPUT_STATUSQ].vq_qsize = VTINPUT_RINGSZ;
735 sc->vsc_queues[VTINPUT_STATUSQ].vq_notify = pci_vtinput_notify_statusq;
737 /* initialize config space */
738 pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_INPUT);
739 pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR);
740 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_INPUTDEV);
741 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_INPUTDEV_OTHER);
742 pci_set_cfgdata8(pi, PCIR_REVID, VIRTIO_REV_INPUT);
743 pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_SUBDEV_INPUT);
744 pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_SUBVEN_INPUT);
746 /* add MSI-X table BAR */
747 if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix()))
749 /* add virtio register */
750 vi_set_io_bar(&sc->vsc_vs, 0);
760 mevent_delete(sc->vsc_evp);
761 if (sc->vsc_eventqueue.events)
762 free(sc->vsc_eventqueue.events);
764 pthread_mutex_destroy(&sc->vsc_mtx);
766 pthread_mutexattr_destroy(&mtx_attr);
775 struct pci_devemu pci_de_vinput = {
776 .pe_emu = "virtio-input",
777 .pe_init = pci_vtinput_init,
778 .pe_legacy_config = pci_vtinput_legacy_config,
779 .pe_barwrite = vi_pci_write,
780 .pe_barread = vi_pci_read,
782 PCI_EMUL_SET(pci_de_vinput);