xref: /illumos-gate/usr/src/cmd/bhyve/common/pci_virtio_input.c (revision 5c4a5fe16715fb423db76577a6883b5bbecdbe45)
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