1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
16 *
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
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * virtio input device emulation.
32 */
33
34
35 #include <sys/param.h>
36 #ifndef WITHOUT_CAPSICUM
37 #include <sys/capsicum.h>
38
39 #include <capsicum_helpers.h>
40 #endif
41 #include <sys/ioctl.h>
42 #include <sys/linker_set.h>
43 #include <sys/uio.h>
44
45 #include <dev/evdev/input.h>
46
47 #include <assert.h>
48 #include <err.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <pthread.h>
52 #include <stddef.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <sysexits.h>
57 #include <unistd.h>
58
59 #include "bhyverun.h"
60 #include "config.h"
61 #include "debug.h"
62 #include "mevent.h"
63 #include "pci_emul.h"
64 #include "virtio.h"
65
66 #define VTINPUT_RINGSZ 64
67
68 #define VTINPUT_MAX_PKT_LEN 10
69
70 /*
71 * Queue definitions.
72 */
73 #define VTINPUT_EVENTQ 0
74 #define VTINPUT_STATUSQ 1
75
76 #define VTINPUT_MAXQ 2
77
78 static int pci_vtinput_debug;
79 #define DPRINTF(params) \
80 if (pci_vtinput_debug) \
81 PRINTLN params
82 #define WPRINTF(params) PRINTLN params
83
84 enum vtinput_config_select {
85 VTINPUT_CFG_UNSET = 0x00,
86 VTINPUT_CFG_ID_NAME = 0x01,
87 VTINPUT_CFG_ID_SERIAL = 0x02,
88 VTINPUT_CFG_ID_DEVIDS = 0x03,
89 VTINPUT_CFG_PROP_BITS = 0x10,
90 VTINPUT_CFG_EV_BITS = 0x11,
91 VTINPUT_CFG_ABS_INFO = 0x12
92 };
93
94 struct vtinput_absinfo {
95 uint32_t min;
96 uint32_t max;
97 uint32_t fuzz;
98 uint32_t flat;
99 uint32_t res;
100 } __packed;
101
102 struct vtinput_devids {
103 uint16_t bustype;
104 uint16_t vendor;
105 uint16_t product;
106 uint16_t version;
107 } __packed;
108
109 struct vtinput_config {
110 uint8_t select;
111 uint8_t subsel;
112 uint8_t size;
113 uint8_t reserved[5];
114 union {
115 char string[128];
116 uint8_t bitmap[128];
117 struct vtinput_absinfo abs;
118 struct vtinput_devids ids;
119 } u;
120 } __packed;
121
122 struct vtinput_event {
123 uint16_t type;
124 uint16_t code;
125 uint32_t value;
126 } __packed;
127
128 struct vtinput_event_elem {
129 struct vtinput_event event;
130 struct iovec iov;
131 uint16_t idx;
132 };
133
134 struct vtinput_eventqueue {
135 struct vtinput_event_elem *events;
136 uint32_t size;
137 uint32_t idx;
138 };
139
140 /*
141 * Per-device softc
142 */
143 struct pci_vtinput_softc {
144 struct virtio_softc vsc_vs;
145 struct vqueue_info vsc_queues[VTINPUT_MAXQ];
146 pthread_mutex_t vsc_mtx;
147 const char *vsc_evdev;
148 int vsc_fd;
149 struct vtinput_config vsc_config;
150 int vsc_config_valid;
151 struct mevent *vsc_evp;
152 struct vtinput_eventqueue vsc_eventqueue;
153 };
154
155 static void pci_vtinput_reset(void *);
156 static int pci_vtinput_cfgread(void *, int, int, uint32_t *);
157 static int pci_vtinput_cfgwrite(void *, int, int, uint32_t);
158
159 static struct virtio_consts vtinput_vi_consts = {
160 .vc_name = "vtinput",
161 .vc_nvq = VTINPUT_MAXQ,
162 .vc_cfgsize = sizeof(struct vtinput_config),
163 .vc_reset = pci_vtinput_reset,
164 .vc_cfgread = pci_vtinput_cfgread,
165 .vc_cfgwrite = pci_vtinput_cfgwrite,
166 .vc_hv_caps = 0,
167 };
168
169 static void
pci_vtinput_reset(void * vsc)170 pci_vtinput_reset(void *vsc)
171 {
172 struct pci_vtinput_softc *sc = vsc;
173
174 DPRINTF(("%s: device reset requested", __func__));
175 vi_reset_dev(&sc->vsc_vs);
176 }
177
178 static void
pci_vtinput_notify_eventq(void * vsc __unused,struct vqueue_info * vq __unused)179 pci_vtinput_notify_eventq(void *vsc __unused, struct vqueue_info *vq __unused)
180 {
181 DPRINTF(("%s", __func__));
182 }
183
184 static void
pci_vtinput_notify_statusq(void * vsc,struct vqueue_info * vq)185 pci_vtinput_notify_statusq(void *vsc, struct vqueue_info *vq)
186 {
187 struct pci_vtinput_softc *sc = vsc;
188
189 while (vq_has_descs(vq)) {
190 /* get descriptor chain */
191 struct iovec iov;
192 struct vi_req req;
193 const int n = vq_getchain(vq, &iov, 1, &req);
194 if (n <= 0) {
195 WPRINTF(("%s: invalid descriptor: %d", __func__, n));
196 return;
197 }
198
199 /* get event */
200 struct vtinput_event event;
201 memcpy(&event, iov.iov_base, sizeof(event));
202
203 /*
204 * on multi touch devices:
205 * - host send EV_MSC to guest
206 * - guest sends EV_MSC back to host
207 * - host writes EV_MSC to evdev
208 * - evdev saves EV_MSC in it's event buffer
209 * - host receives an extra EV_MSC by reading the evdev event
210 * buffer
211 * - frames become larger and larger
212 * avoid endless loops by ignoring EV_MSC
213 */
214 if (event.type == EV_MSC) {
215 vq_relchain(vq, req.idx, sizeof(event));
216 continue;
217 }
218
219 /* send event to evdev */
220 struct input_event host_event;
221 host_event.type = event.type;
222 host_event.code = event.code;
223 host_event.value = event.value;
224 if (gettimeofday(&host_event.time, NULL) != 0) {
225 WPRINTF(("%s: failed gettimeofday", __func__));
226 }
227 if (write(sc->vsc_fd, &host_event, sizeof(host_event)) == -1) {
228 WPRINTF(("%s: failed to write host_event", __func__));
229 }
230
231 vq_relchain(vq, req.idx, sizeof(event));
232 }
233 vq_endchains(vq, 1);
234 }
235
236 static int
pci_vtinput_get_bitmap(struct pci_vtinput_softc * sc,int cmd,int count)237 pci_vtinput_get_bitmap(struct pci_vtinput_softc *sc, int cmd, int count)
238 {
239 if (count <= 0 || !sc) {
240 return (-1);
241 }
242
243 /* query bitmap */
244 memset(sc->vsc_config.u.bitmap, 0, sizeof(sc->vsc_config.u.bitmap));
245 if (ioctl(sc->vsc_fd, cmd, sc->vsc_config.u.bitmap) < 0) {
246 return (-1);
247 }
248
249 /* get number of set bytes in bitmap */
250 for (int i = count - 1; i >= 0; i--) {
251 if (sc->vsc_config.u.bitmap[i]) {
252 return i + 1;
253 }
254 }
255
256 return (-1);
257 }
258
259 static int
pci_vtinput_read_config_id_name(struct pci_vtinput_softc * sc)260 pci_vtinput_read_config_id_name(struct pci_vtinput_softc *sc)
261 {
262 char name[128];
263 if (ioctl(sc->vsc_fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
264 return (1);
265 }
266
267 memcpy(sc->vsc_config.u.string, name, sizeof(name));
268 sc->vsc_config.size = strnlen(name, sizeof(name));
269
270 return (0);
271 }
272
273 static int
pci_vtinput_read_config_id_serial(struct pci_vtinput_softc * sc)274 pci_vtinput_read_config_id_serial(struct pci_vtinput_softc *sc)
275 {
276 /* serial isn't supported */
277 sc->vsc_config.size = 0;
278
279 return (0);
280 }
281
282 static int
pci_vtinput_read_config_id_devids(struct pci_vtinput_softc * sc)283 pci_vtinput_read_config_id_devids(struct pci_vtinput_softc *sc)
284 {
285 struct input_id devids;
286 if (ioctl(sc->vsc_fd, EVIOCGID, &devids)) {
287 return (1);
288 }
289
290 sc->vsc_config.u.ids.bustype = devids.bustype;
291 sc->vsc_config.u.ids.vendor = devids.vendor;
292 sc->vsc_config.u.ids.product = devids.product;
293 sc->vsc_config.u.ids.version = devids.version;
294 sc->vsc_config.size = sizeof(struct vtinput_devids);
295
296 return (0);
297 }
298
299 static int
pci_vtinput_read_config_prop_bits(struct pci_vtinput_softc * sc)300 pci_vtinput_read_config_prop_bits(struct pci_vtinput_softc *sc)
301 {
302 /*
303 * Evdev bitmap countains 1 bit per count. Additionally evdev bitmaps
304 * are arrays of longs instead of chars. Calculate how many longs are
305 * required for evdev bitmap. Multiply that with sizeof(long) to get the
306 * number of elements.
307 */
308 const int count = howmany(INPUT_PROP_CNT, sizeof(long) * 8) *
309 sizeof(long);
310 const unsigned int cmd = EVIOCGPROP(count);
311 const int size = pci_vtinput_get_bitmap(sc, cmd, count);
312 if (size <= 0) {
313 return (1);
314 }
315
316 sc->vsc_config.size = size;
317
318 return (0);
319 }
320
321 static int
pci_vtinput_read_config_ev_bits(struct pci_vtinput_softc * sc,uint8_t type)322 pci_vtinput_read_config_ev_bits(struct pci_vtinput_softc *sc, uint8_t type)
323 {
324 int count;
325
326 switch (type) {
327 case EV_KEY:
328 count = KEY_CNT;
329 break;
330 case EV_REL:
331 count = REL_CNT;
332 break;
333 case EV_ABS:
334 count = ABS_CNT;
335 break;
336 case EV_MSC:
337 count = MSC_CNT;
338 break;
339 case EV_SW:
340 count = SW_CNT;
341 break;
342 case EV_LED:
343 count = LED_CNT;
344 break;
345 default:
346 return (1);
347 }
348
349 /*
350 * Evdev bitmap countains 1 bit per count. Additionally evdev bitmaps
351 * are arrays of longs instead of chars. Calculate how many longs are
352 * required for evdev bitmap. Multiply that with sizeof(long) to get the
353 * number of elements.
354 */
355 count = howmany(count, sizeof(long) * 8) * sizeof(long);
356 const unsigned int cmd = EVIOCGBIT(sc->vsc_config.subsel, count);
357 const int size = pci_vtinput_get_bitmap(sc, cmd, count);
358 if (size <= 0) {
359 return (1);
360 }
361
362 sc->vsc_config.size = size;
363
364 return (0);
365 }
366
367 static int
pci_vtinput_read_config_abs_info(struct pci_vtinput_softc * sc)368 pci_vtinput_read_config_abs_info(struct pci_vtinput_softc *sc)
369 {
370 /* check if evdev has EV_ABS */
371 if (!pci_vtinput_read_config_ev_bits(sc, EV_ABS)) {
372 return (1);
373 }
374
375 /* get abs information */
376 struct input_absinfo abs;
377 if (ioctl(sc->vsc_fd, EVIOCGABS(sc->vsc_config.subsel), &abs) < 0) {
378 return (1);
379 }
380
381 /* save abs information */
382 sc->vsc_config.u.abs.min = abs.minimum;
383 sc->vsc_config.u.abs.max = abs.maximum;
384 sc->vsc_config.u.abs.fuzz = abs.fuzz;
385 sc->vsc_config.u.abs.flat = abs.flat;
386 sc->vsc_config.u.abs.res = abs.resolution;
387 sc->vsc_config.size = sizeof(struct vtinput_absinfo);
388
389 return (0);
390 }
391
392 static int
pci_vtinput_read_config(struct pci_vtinput_softc * sc)393 pci_vtinput_read_config(struct pci_vtinput_softc *sc)
394 {
395 switch (sc->vsc_config.select) {
396 case VTINPUT_CFG_UNSET:
397 return (0);
398 case VTINPUT_CFG_ID_NAME:
399 return pci_vtinput_read_config_id_name(sc);
400 case VTINPUT_CFG_ID_SERIAL:
401 return pci_vtinput_read_config_id_serial(sc);
402 case VTINPUT_CFG_ID_DEVIDS:
403 return pci_vtinput_read_config_id_devids(sc);
404 case VTINPUT_CFG_PROP_BITS:
405 return pci_vtinput_read_config_prop_bits(sc);
406 case VTINPUT_CFG_EV_BITS:
407 return pci_vtinput_read_config_ev_bits(
408 sc, sc->vsc_config.subsel);
409 case VTINPUT_CFG_ABS_INFO:
410 return pci_vtinput_read_config_abs_info(sc);
411 default:
412 return (1);
413 }
414 }
415
416 static int
pci_vtinput_cfgread(void * vsc,int offset,int size,uint32_t * retval)417 pci_vtinput_cfgread(void *vsc, int offset, int size, uint32_t *retval)
418 {
419 struct pci_vtinput_softc *sc = vsc;
420
421 /* check for valid offset and size */
422 if (offset + size > (int)sizeof(struct vtinput_config)) {
423 WPRINTF(("%s: read to invalid offset/size %d/%d", __func__,
424 offset, size));
425 memset(retval, 0, size);
426 return (0);
427 }
428
429 /* read new config values, if select and subsel changed. */
430 if (!sc->vsc_config_valid) {
431 if (pci_vtinput_read_config(sc) != 0) {
432 DPRINTF(("%s: could not read config %d/%d", __func__,
433 sc->vsc_config.select, sc->vsc_config.subsel));
434 memset(retval, 0, size);
435 return (0);
436 }
437 sc->vsc_config_valid = 1;
438 }
439
440 uint8_t *ptr = (uint8_t *)&sc->vsc_config;
441 memcpy(retval, ptr + offset, size);
442
443 return (0);
444 }
445
446 static int
pci_vtinput_cfgwrite(void * vsc,int offset,int size,uint32_t value)447 pci_vtinput_cfgwrite(void *vsc, int offset, int size, uint32_t value)
448 {
449 struct pci_vtinput_softc *sc = vsc;
450
451 /* guest can only write to select and subsel fields */
452 if (offset + size > 2) {
453 WPRINTF(("%s: write to readonly reg %d", __func__, offset));
454 return (1);
455 }
456
457 /* copy value into config */
458 uint8_t *ptr = (uint8_t *)&sc->vsc_config;
459 memcpy(ptr + offset, &value, size);
460
461 /* select/subsel changed, query new config on next cfgread */
462 sc->vsc_config_valid = 0;
463
464 return (0);
465 }
466
467 static int
vtinput_eventqueue_add_event(struct vtinput_eventqueue * queue,struct input_event * e)468 vtinput_eventqueue_add_event(
469 struct vtinput_eventqueue *queue, struct input_event *e)
470 {
471 /* check if queue is full */
472 if (queue->idx >= queue->size) {
473 /* alloc new elements for queue */
474 const uint32_t newSize = queue->idx;
475 void *newPtr = realloc(queue->events,
476 queue->size * sizeof(struct vtinput_event_elem));
477 if (newPtr == NULL) {
478 WPRINTF(("%s: realloc memory for eventqueue failed!",
479 __func__));
480 return (1);
481 }
482 queue->events = newPtr;
483 queue->size = newSize;
484 }
485
486 /* save event */
487 struct vtinput_event *event = &queue->events[queue->idx].event;
488 event->type = e->type;
489 event->code = e->code;
490 event->value = e->value;
491 queue->idx++;
492
493 return (0);
494 }
495
496 static void
vtinput_eventqueue_clear(struct vtinput_eventqueue * queue)497 vtinput_eventqueue_clear(struct vtinput_eventqueue *queue)
498 {
499 /* just reset index to clear queue */
500 queue->idx = 0;
501 }
502
503 static void
vtinput_eventqueue_send_events(struct vtinput_eventqueue * queue,struct vqueue_info * vq)504 vtinput_eventqueue_send_events(
505 struct vtinput_eventqueue *queue, struct vqueue_info *vq)
506 {
507 /*
508 * First iteration through eventqueue:
509 * Get descriptor chains.
510 */
511 for (uint32_t i = 0; i < queue->idx; ++i) {
512 /* get descriptor */
513 if (!vq_has_descs(vq)) {
514 /*
515 * We don't have enough descriptors for all events.
516 * Return chains back to guest.
517 */
518 vq_retchains(vq, i);
519 WPRINTF((
520 "%s: not enough available descriptors, dropping %d events",
521 __func__, queue->idx));
522 goto done;
523 }
524
525 /* get descriptor chain */
526 struct iovec iov;
527 struct vi_req req;
528 const int n = vq_getchain(vq, &iov, 1, &req);
529 if (n <= 0) {
530 WPRINTF(("%s: invalid descriptor: %d", __func__, n));
531 return;
532 }
533 if (n != 1) {
534 WPRINTF(
535 ("%s: invalid number of descriptors in chain: %d",
536 __func__, n));
537 /* release invalid chain */
538 vq_relchain(vq, req.idx, 0);
539 return;
540 }
541 if (iov.iov_len < sizeof(struct vtinput_event)) {
542 WPRINTF(("%s: invalid descriptor length: %lu", __func__,
543 iov.iov_len));
544 /* release invalid chain */
545 vq_relchain(vq, req.idx, 0);
546 return;
547 }
548
549 /* save descriptor */
550 queue->events[i].iov = iov;
551 queue->events[i].idx = req.idx;
552 }
553
554 /*
555 * Second iteration through eventqueue:
556 * Send events to guest by releasing chains
557 */
558 for (uint32_t i = 0; i < queue->idx; ++i) {
559 struct vtinput_event_elem event = queue->events[i];
560 memcpy(event.iov.iov_base, &event.event,
561 sizeof(struct vtinput_event));
562 vq_relchain(vq, event.idx, sizeof(struct vtinput_event));
563 }
564 done:
565 /* clear queue and send interrupt to guest */
566 vtinput_eventqueue_clear(queue);
567 vq_endchains(vq, 1);
568 }
569
570 static int
vtinput_read_event_from_host(int fd,struct input_event * event)571 vtinput_read_event_from_host(int fd, struct input_event *event)
572 {
573 const int len = read(fd, event, sizeof(struct input_event));
574 if (len != sizeof(struct input_event)) {
575 if (len == -1 && errno != EAGAIN) {
576 WPRINTF(("%s: event read failed! len = %d, errno = %d",
577 __func__, len, errno));
578 }
579
580 /* host doesn't have more events for us */
581 return (1);
582 }
583
584 return (0);
585 }
586
587 static void
vtinput_read_event(int fd __attribute ((unused)),enum ev_type t,void * arg)588 vtinput_read_event(int fd __attribute((unused)),
589 enum ev_type t __attribute__((unused)), void *arg __attribute__((unused)))
590 {
591 struct pci_vtinput_softc *sc = arg;
592
593 /* skip if driver isn't ready */
594 if (!(sc->vsc_vs.vs_status & VIRTIO_CONFIG_STATUS_DRIVER_OK))
595 return;
596
597 /* read all events from host */
598 struct input_event event;
599 while (vtinput_read_event_from_host(sc->vsc_fd, &event) == 0) {
600 /* add events to our queue */
601 vtinput_eventqueue_add_event(&sc->vsc_eventqueue, &event);
602
603 /* only send events to guest on EV_SYN or SYN_REPORT */
604 if (event.type != EV_SYN || event.type != SYN_REPORT) {
605 continue;
606 }
607
608 /* send host events to guest */
609 vtinput_eventqueue_send_events(
610 &sc->vsc_eventqueue, &sc->vsc_queues[VTINPUT_EVENTQ]);
611 }
612 }
613
614 static int
pci_vtinput_legacy_config(nvlist_t * nvl,const char * opts)615 pci_vtinput_legacy_config(nvlist_t *nvl, const char *opts)
616 {
617 if (opts == NULL)
618 return (-1);
619
620 /*
621 * parse opts:
622 * virtio-input,/dev/input/eventX
623 */
624 char *cp = strchr(opts, ',');
625 if (cp == NULL) {
626 set_config_value_node(nvl, "path", opts);
627 return (0);
628 }
629 char *path = strndup(opts, cp - opts);
630 set_config_value_node(nvl, "path", path);
631 free(path);
632
633 return (pci_parse_legacy_config(nvl, cp + 1));
634 }
635
636 static int
pci_vtinput_init(struct pci_devinst * pi,nvlist_t * nvl)637 pci_vtinput_init(struct pci_devinst *pi, nvlist_t *nvl)
638 {
639 struct pci_vtinput_softc *sc;
640
641 /*
642 * Keep it here.
643 * Else it's possible to access it uninitialized by jumping to failed.
644 */
645 pthread_mutexattr_t mtx_attr = NULL;
646
647 sc = calloc(1, sizeof(struct pci_vtinput_softc));
648
649 sc->vsc_evdev = get_config_value_node(nvl, "path");
650 if (sc->vsc_evdev == NULL) {
651 WPRINTF(("%s: missing required path config value", __func__));
652 goto failed;
653 }
654
655 /*
656 * open evdev by using non blocking I/O:
657 * read from /dev/input/eventX would block our thread otherwise
658 */
659 sc->vsc_fd = open(sc->vsc_evdev, O_RDWR | O_NONBLOCK);
660 if (sc->vsc_fd < 0) {
661 WPRINTF(("%s: failed to open %s", __func__, sc->vsc_evdev));
662 goto failed;
663 }
664
665 /* check if evdev is really a evdev */
666 int evversion;
667 int error = ioctl(sc->vsc_fd, EVIOCGVERSION, &evversion);
668 if (error < 0) {
669 WPRINTF(("%s: %s is no evdev", __func__, sc->vsc_evdev));
670 goto failed;
671 }
672
673 /* gain exclusive access to evdev */
674 error = ioctl(sc->vsc_fd, EVIOCGRAB, 1);
675 if (error < 0) {
676 WPRINTF(("%s: failed to grab %s", __func__, sc->vsc_evdev));
677 goto failed;
678 }
679
680 if (pthread_mutexattr_init(&mtx_attr)) {
681 WPRINTF(("%s: init mutexattr failed", __func__));
682 goto failed;
683 }
684 if (pthread_mutexattr_settype(&mtx_attr, PTHREAD_MUTEX_RECURSIVE)) {
685 WPRINTF(("%s: settype mutexattr failed", __func__));
686 goto failed;
687 }
688 if (pthread_mutex_init(&sc->vsc_mtx, &mtx_attr)) {
689 WPRINTF(("%s: init mutex failed", __func__));
690 goto failed;
691 }
692
693 /* init softc */
694 sc->vsc_eventqueue.idx = 0;
695 sc->vsc_eventqueue.size = VTINPUT_MAX_PKT_LEN;
696 sc->vsc_eventqueue.events = calloc(
697 sc->vsc_eventqueue.size, sizeof(struct vtinput_event_elem));
698 sc->vsc_config_valid = 0;
699 if (sc->vsc_eventqueue.events == NULL) {
700 WPRINTF(("%s: failed to alloc eventqueue", __func__));
701 goto failed;
702 }
703
704 /* register event handler */
705 sc->vsc_evp = mevent_add(sc->vsc_fd, EVF_READ, vtinput_read_event, sc);
706 if (sc->vsc_evp == NULL) {
707 WPRINTF(("%s: could not register mevent", __func__));
708 goto failed;
709 }
710
711 #ifndef WITHOUT_CAPSICUM
712 cap_rights_t rights;
713 cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE);
714 if (caph_rights_limit(sc->vsc_fd, &rights) == -1) {
715 errx(EX_OSERR, "Unable to apply rights for sandbox");
716 }
717 #endif
718
719 /* link virtio to softc */
720 vi_softc_linkup(
721 &sc->vsc_vs, &vtinput_vi_consts, sc, pi, sc->vsc_queues);
722 sc->vsc_vs.vs_mtx = &sc->vsc_mtx;
723
724 /* init virtio queues */
725 sc->vsc_queues[VTINPUT_EVENTQ].vq_qsize = VTINPUT_RINGSZ;
726 sc->vsc_queues[VTINPUT_EVENTQ].vq_notify = pci_vtinput_notify_eventq;
727 sc->vsc_queues[VTINPUT_STATUSQ].vq_qsize = VTINPUT_RINGSZ;
728 sc->vsc_queues[VTINPUT_STATUSQ].vq_notify = pci_vtinput_notify_statusq;
729
730 /* initialize config space */
731 pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_INPUT);
732 pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR);
733 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_INPUTDEV);
734 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_INPUTDEV_OTHER);
735 pci_set_cfgdata8(pi, PCIR_REVID, VIRTIO_REV_INPUT);
736 pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_SUBDEV_INPUT);
737 pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_SUBVEN_INPUT);
738
739 /* add MSI-X table BAR */
740 if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix()))
741 goto failed;
742 /* add virtio register */
743 vi_set_io_bar(&sc->vsc_vs, 0);
744
745 return (0);
746
747 failed:
748 if (sc == NULL) {
749 return (-1);
750 }
751
752 if (sc->vsc_evp)
753 mevent_delete(sc->vsc_evp);
754 if (sc->vsc_eventqueue.events)
755 free(sc->vsc_eventqueue.events);
756 if (sc->vsc_mtx)
757 pthread_mutex_destroy(&sc->vsc_mtx);
758 if (mtx_attr)
759 pthread_mutexattr_destroy(&mtx_attr);
760 if (sc->vsc_fd)
761 close(sc->vsc_fd);
762
763 free(sc);
764
765 return (-1);
766 }
767
768 static const struct pci_devemu pci_de_vinput = {
769 .pe_emu = "virtio-input",
770 .pe_init = pci_vtinput_init,
771 .pe_legacy_config = pci_vtinput_legacy_config,
772 .pe_barwrite = vi_pci_write,
773 .pe_barread = vi_pci_read,
774 };
775 PCI_EMUL_SET(pci_de_vinput);
776