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