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