1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2011 NetApp, Inc. 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 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/linker_set.h> 36 #include <sys/select.h> 37 #include <sys/uio.h> 38 #include <sys/ioctl.h> 39 #include <machine/vmm_snapshot.h> 40 #include <net/ethernet.h> 41 #include <net/if.h> /* IFNAMSIZ */ 42 43 #include <err.h> 44 #include <errno.h> 45 #include <fcntl.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <stdint.h> 49 #include <string.h> 50 #include <strings.h> 51 #include <unistd.h> 52 #include <assert.h> 53 #include <pthread.h> 54 #include <pthread_np.h> 55 56 #include "bhyverun.h" 57 #include "debug.h" 58 #include "pci_emul.h" 59 #include "mevent.h" 60 #include "virtio.h" 61 #include "net_utils.h" 62 #include "net_backends.h" 63 #include "iov.h" 64 65 #define VTNET_RINGSZ 1024 66 67 #define VTNET_MAXSEGS 256 68 69 #define VTNET_MAX_PKT_LEN (65536 + 64) 70 71 #define VTNET_MIN_MTU ETHERMIN 72 #define VTNET_MAX_MTU 65535 73 74 #define VTNET_S_HOSTCAPS \ 75 ( VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | \ 76 VIRTIO_F_NOTIFY_ON_EMPTY | VIRTIO_RING_F_INDIRECT_DESC) 77 78 /* 79 * PCI config-space "registers" 80 */ 81 struct virtio_net_config { 82 uint8_t mac[6]; 83 uint16_t status; 84 uint16_t max_virtqueue_pairs; 85 uint16_t mtu; 86 } __packed; 87 88 /* 89 * Queue definitions. 90 */ 91 #define VTNET_RXQ 0 92 #define VTNET_TXQ 1 93 #define VTNET_CTLQ 2 /* NB: not yet supported */ 94 95 #define VTNET_MAXQ 3 96 97 /* 98 * Debug printf 99 */ 100 static int pci_vtnet_debug; 101 #define DPRINTF(params) if (pci_vtnet_debug) PRINTLN params 102 #define WPRINTF(params) PRINTLN params 103 104 /* 105 * Per-device softc 106 */ 107 struct pci_vtnet_softc { 108 struct virtio_softc vsc_vs; 109 struct vqueue_info vsc_queues[VTNET_MAXQ - 1]; 110 pthread_mutex_t vsc_mtx; 111 112 net_backend_t *vsc_be; 113 114 bool features_negotiated; /* protected by rx_mtx */ 115 116 int resetting; /* protected by tx_mtx */ 117 118 uint64_t vsc_features; /* negotiated features */ 119 120 pthread_mutex_t rx_mtx; 121 int rx_merge; /* merged rx bufs in use */ 122 123 pthread_t tx_tid; 124 pthread_mutex_t tx_mtx; 125 pthread_cond_t tx_cond; 126 int tx_in_progress; 127 128 size_t vhdrlen; 129 size_t be_vhdrlen; 130 131 struct virtio_net_config vsc_config; 132 struct virtio_consts vsc_consts; 133 }; 134 135 static void pci_vtnet_reset(void *); 136 /* static void pci_vtnet_notify(void *, struct vqueue_info *); */ 137 static int pci_vtnet_cfgread(void *, int, int, uint32_t *); 138 static int pci_vtnet_cfgwrite(void *, int, int, uint32_t); 139 static void pci_vtnet_neg_features(void *, uint64_t); 140 #ifdef BHYVE_SNAPSHOT 141 static void pci_vtnet_pause(void *); 142 static void pci_vtnet_resume(void *); 143 static int pci_vtnet_snapshot(void *, struct vm_snapshot_meta *); 144 #endif 145 146 static struct virtio_consts vtnet_vi_consts = { 147 "vtnet", /* our name */ 148 VTNET_MAXQ - 1, /* we currently support 2 virtqueues */ 149 sizeof(struct virtio_net_config), /* config reg size */ 150 pci_vtnet_reset, /* reset */ 151 NULL, /* device-wide qnotify -- not used */ 152 pci_vtnet_cfgread, /* read PCI config */ 153 pci_vtnet_cfgwrite, /* write PCI config */ 154 pci_vtnet_neg_features, /* apply negotiated features */ 155 VTNET_S_HOSTCAPS, /* our capabilities */ 156 #ifdef BHYVE_SNAPSHOT 157 pci_vtnet_pause, /* pause rx/tx threads */ 158 pci_vtnet_resume, /* resume rx/tx threads */ 159 pci_vtnet_snapshot, /* save / restore device state */ 160 #endif 161 }; 162 163 static void 164 pci_vtnet_reset(void *vsc) 165 { 166 struct pci_vtnet_softc *sc = vsc; 167 168 DPRINTF(("vtnet: device reset requested !")); 169 170 /* Acquire the RX lock to block RX processing. */ 171 pthread_mutex_lock(&sc->rx_mtx); 172 173 /* 174 * Make sure receive operation is disabled at least until we 175 * re-negotiate the features, since receive operation depends 176 * on the value of sc->rx_merge and the header length, which 177 * are both set in pci_vtnet_neg_features(). 178 * Receive operation will be enabled again once the guest adds 179 * the first receive buffers and kicks us. 180 */ 181 sc->features_negotiated = false; 182 netbe_rx_disable(sc->vsc_be); 183 184 /* Set sc->resetting and give a chance to the TX thread to stop. */ 185 pthread_mutex_lock(&sc->tx_mtx); 186 sc->resetting = 1; 187 while (sc->tx_in_progress) { 188 pthread_mutex_unlock(&sc->tx_mtx); 189 usleep(10000); 190 pthread_mutex_lock(&sc->tx_mtx); 191 } 192 193 /* 194 * Now reset rings, MSI-X vectors, and negotiated capabilities. 195 * Do that with the TX lock held, since we need to reset 196 * sc->resetting. 197 */ 198 vi_reset_dev(&sc->vsc_vs); 199 200 sc->resetting = 0; 201 pthread_mutex_unlock(&sc->tx_mtx); 202 pthread_mutex_unlock(&sc->rx_mtx); 203 } 204 205 static __inline struct iovec * 206 iov_trim_hdr(struct iovec *iov, int *iovcnt, unsigned int hlen) 207 { 208 struct iovec *riov; 209 210 if (iov[0].iov_len < hlen) { 211 /* 212 * Not enough header space in the first fragment. 213 * That's not ok for us. 214 */ 215 return NULL; 216 } 217 218 iov[0].iov_len -= hlen; 219 if (iov[0].iov_len == 0) { 220 *iovcnt -= 1; 221 if (*iovcnt == 0) { 222 /* 223 * Only space for the header. That's not 224 * enough for us. 225 */ 226 return NULL; 227 } 228 riov = &iov[1]; 229 } else { 230 iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base + hlen); 231 riov = &iov[0]; 232 } 233 234 return (riov); 235 } 236 237 struct virtio_mrg_rxbuf_info { 238 uint16_t idx; 239 uint16_t pad; 240 uint32_t len; 241 }; 242 243 static void 244 pci_vtnet_rx(struct pci_vtnet_softc *sc) 245 { 246 int prepend_hdr_len = sc->vhdrlen - sc->be_vhdrlen; 247 struct virtio_mrg_rxbuf_info info[VTNET_MAXSEGS]; 248 struct iovec iov[VTNET_MAXSEGS + 1]; 249 struct vqueue_info *vq; 250 251 vq = &sc->vsc_queues[VTNET_RXQ]; 252 253 /* Features must be negotiated */ 254 if (!sc->features_negotiated) { 255 return; 256 } 257 258 for (;;) { 259 struct virtio_net_rxhdr *hdr; 260 uint32_t riov_bytes; 261 struct iovec *riov; 262 uint32_t ulen; 263 int riov_len; 264 int n_chains; 265 ssize_t rlen; 266 ssize_t plen; 267 268 plen = netbe_peek_recvlen(sc->vsc_be); 269 if (plen <= 0) { 270 /* 271 * No more packets (plen == 0), or backend errored 272 * (plen < 0). Interrupt if needed and stop. 273 */ 274 vq_endchains(vq, /*used_all_avail=*/0); 275 return; 276 } 277 plen += prepend_hdr_len; 278 279 /* 280 * Get a descriptor chain to store the next ingress 281 * packet. In case of mergeable rx buffers, get as 282 * many chains as necessary in order to make room 283 * for plen bytes. 284 */ 285 riov_bytes = 0; 286 riov_len = 0; 287 riov = iov; 288 n_chains = 0; 289 do { 290 int n = vq_getchain(vq, &info[n_chains].idx, riov, 291 VTNET_MAXSEGS - riov_len, NULL); 292 293 if (n == 0) { 294 /* 295 * No rx buffers. Enable RX kicks and double 296 * check. 297 */ 298 vq_kick_enable(vq); 299 if (!vq_has_descs(vq)) { 300 /* 301 * Still no buffers. Return the unused 302 * chains (if any), interrupt if needed 303 * (including for NOTIFY_ON_EMPTY), and 304 * disable the backend until the next 305 * kick. 306 */ 307 vq_retchains(vq, n_chains); 308 vq_endchains(vq, /*used_all_avail=*/1); 309 netbe_rx_disable(sc->vsc_be); 310 return; 311 } 312 313 /* More rx buffers found, so keep going. */ 314 vq_kick_disable(vq); 315 continue; 316 } 317 assert(n >= 1 && riov_len + n <= VTNET_MAXSEGS); 318 riov_len += n; 319 if (!sc->rx_merge) { 320 n_chains = 1; 321 break; 322 } 323 info[n_chains].len = (uint32_t)count_iov(riov, n); 324 riov_bytes += info[n_chains].len; 325 riov += n; 326 n_chains++; 327 } while (riov_bytes < plen && riov_len < VTNET_MAXSEGS); 328 329 riov = iov; 330 hdr = riov[0].iov_base; 331 if (prepend_hdr_len > 0) { 332 /* 333 * The frontend uses a virtio-net header, but the 334 * backend does not. We need to prepend a zeroed 335 * header. 336 */ 337 riov = iov_trim_hdr(riov, &riov_len, prepend_hdr_len); 338 if (riov == NULL) { 339 /* 340 * The first collected chain is nonsensical, 341 * as it is not even enough to store the 342 * virtio-net header. Just drop it. 343 */ 344 vq_relchain(vq, info[0].idx, 0); 345 vq_retchains(vq, n_chains - 1); 346 continue; 347 } 348 memset(hdr, 0, prepend_hdr_len); 349 } 350 351 rlen = netbe_recv(sc->vsc_be, riov, riov_len); 352 if (rlen != plen - prepend_hdr_len) { 353 /* 354 * If this happens it means there is something 355 * wrong with the backend (e.g., some other 356 * process is stealing our packets). 357 */ 358 WPRINTF(("netbe_recv: expected %zd bytes, " 359 "got %zd", plen - prepend_hdr_len, rlen)); 360 vq_retchains(vq, n_chains); 361 continue; 362 } 363 364 ulen = (uint32_t)plen; 365 366 /* 367 * Publish the used buffers to the guest, reporting the 368 * number of bytes that we wrote. 369 */ 370 if (!sc->rx_merge) { 371 vq_relchain(vq, info[0].idx, ulen); 372 } else { 373 uint32_t iolen; 374 int i = 0; 375 376 do { 377 iolen = info[i].len; 378 if (iolen > ulen) { 379 iolen = ulen; 380 } 381 vq_relchain_prepare(vq, info[i].idx, iolen); 382 ulen -= iolen; 383 i++; 384 } while (ulen > 0); 385 386 hdr->vrh_bufs = i; 387 vq_relchain_publish(vq); 388 assert(i == n_chains); 389 } 390 } 391 392 } 393 394 /* 395 * Called when there is read activity on the backend file descriptor. 396 * Each buffer posted by the guest is assumed to be able to contain 397 * an entire ethernet frame + rx header. 398 */ 399 static void 400 pci_vtnet_rx_callback(int fd, enum ev_type type, void *param) 401 { 402 struct pci_vtnet_softc *sc = param; 403 404 pthread_mutex_lock(&sc->rx_mtx); 405 pci_vtnet_rx(sc); 406 pthread_mutex_unlock(&sc->rx_mtx); 407 408 } 409 410 /* Called on RX kick. */ 411 static void 412 pci_vtnet_ping_rxq(void *vsc, struct vqueue_info *vq) 413 { 414 struct pci_vtnet_softc *sc = vsc; 415 416 /* 417 * A qnotify means that the rx process can now begin. 418 * Enable RX only if features are negotiated. 419 */ 420 pthread_mutex_lock(&sc->rx_mtx); 421 if (!sc->features_negotiated) { 422 pthread_mutex_unlock(&sc->rx_mtx); 423 return; 424 } 425 426 vq_kick_disable(vq); 427 netbe_rx_enable(sc->vsc_be); 428 pthread_mutex_unlock(&sc->rx_mtx); 429 } 430 431 /* TX virtqueue processing, called by the TX thread. */ 432 static void 433 pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq) 434 { 435 struct iovec iov[VTNET_MAXSEGS + 1]; 436 struct iovec *siov = iov; 437 uint16_t idx; 438 ssize_t len; 439 int n; 440 441 /* 442 * Obtain chain of descriptors. The first descriptor also 443 * contains the virtio-net header. 444 */ 445 n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); 446 assert(n >= 1 && n <= VTNET_MAXSEGS); 447 448 if (sc->vhdrlen != sc->be_vhdrlen) { 449 /* 450 * The frontend uses a virtio-net header, but the backend 451 * does not. We simply strip the header and ignore it, as 452 * it should be zero-filled. 453 */ 454 siov = iov_trim_hdr(siov, &n, sc->vhdrlen); 455 } 456 457 if (siov == NULL) { 458 /* The chain is nonsensical. Just drop it. */ 459 len = 0; 460 } else { 461 len = netbe_send(sc->vsc_be, siov, n); 462 if (len < 0) { 463 /* 464 * If send failed, report that 0 bytes 465 * were read. 466 */ 467 len = 0; 468 } 469 } 470 471 /* 472 * Return the processed chain to the guest, reporting 473 * the number of bytes that we read. 474 */ 475 vq_relchain(vq, idx, len); 476 } 477 478 /* Called on TX kick. */ 479 static void 480 pci_vtnet_ping_txq(void *vsc, struct vqueue_info *vq) 481 { 482 struct pci_vtnet_softc *sc = vsc; 483 484 /* 485 * Any ring entries to process? 486 */ 487 if (!vq_has_descs(vq)) 488 return; 489 490 /* Signal the tx thread for processing */ 491 pthread_mutex_lock(&sc->tx_mtx); 492 vq_kick_disable(vq); 493 if (sc->tx_in_progress == 0) 494 pthread_cond_signal(&sc->tx_cond); 495 pthread_mutex_unlock(&sc->tx_mtx); 496 } 497 498 /* 499 * Thread which will handle processing of TX desc 500 */ 501 static void * 502 pci_vtnet_tx_thread(void *param) 503 { 504 struct pci_vtnet_softc *sc = param; 505 struct vqueue_info *vq; 506 int error; 507 508 vq = &sc->vsc_queues[VTNET_TXQ]; 509 510 /* 511 * Let us wait till the tx queue pointers get initialised & 512 * first tx signaled 513 */ 514 pthread_mutex_lock(&sc->tx_mtx); 515 error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); 516 assert(error == 0); 517 518 for (;;) { 519 /* note - tx mutex is locked here */ 520 while (sc->resetting || !vq_has_descs(vq)) { 521 vq_kick_enable(vq); 522 if (!sc->resetting && vq_has_descs(vq)) 523 break; 524 525 sc->tx_in_progress = 0; 526 error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); 527 assert(error == 0); 528 } 529 vq_kick_disable(vq); 530 sc->tx_in_progress = 1; 531 pthread_mutex_unlock(&sc->tx_mtx); 532 533 do { 534 /* 535 * Run through entries, placing them into 536 * iovecs and sending when an end-of-packet 537 * is found 538 */ 539 pci_vtnet_proctx(sc, vq); 540 } while (vq_has_descs(vq)); 541 542 /* 543 * Generate an interrupt if needed. 544 */ 545 vq_endchains(vq, /*used_all_avail=*/1); 546 547 pthread_mutex_lock(&sc->tx_mtx); 548 } 549 } 550 551 #ifdef notyet 552 static void 553 pci_vtnet_ping_ctlq(void *vsc, struct vqueue_info *vq) 554 { 555 556 DPRINTF(("vtnet: control qnotify!")); 557 } 558 #endif 559 560 static int 561 pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) 562 { 563 struct pci_vtnet_softc *sc; 564 char tname[MAXCOMLEN + 1]; 565 int mac_provided; 566 int mtu_provided; 567 unsigned long mtu = ETHERMTU; 568 569 /* 570 * Allocate data structures for further virtio initializations. 571 * sc also contains a copy of vtnet_vi_consts, since capabilities 572 * change depending on the backend. 573 */ 574 sc = calloc(1, sizeof(struct pci_vtnet_softc)); 575 576 sc->vsc_consts = vtnet_vi_consts; 577 pthread_mutex_init(&sc->vsc_mtx, NULL); 578 579 sc->vsc_queues[VTNET_RXQ].vq_qsize = VTNET_RINGSZ; 580 sc->vsc_queues[VTNET_RXQ].vq_notify = pci_vtnet_ping_rxq; 581 sc->vsc_queues[VTNET_TXQ].vq_qsize = VTNET_RINGSZ; 582 sc->vsc_queues[VTNET_TXQ].vq_notify = pci_vtnet_ping_txq; 583 #ifdef notyet 584 sc->vsc_queues[VTNET_CTLQ].vq_qsize = VTNET_RINGSZ; 585 sc->vsc_queues[VTNET_CTLQ].vq_notify = pci_vtnet_ping_ctlq; 586 #endif 587 588 /* 589 * Attempt to open the backend device and read the MAC address 590 * if specified. 591 */ 592 mac_provided = 0; 593 mtu_provided = 0; 594 if (opts != NULL) { 595 char *optscopy; 596 char *vtopts; 597 int err = 0; 598 599 /* Get the device name. */ 600 optscopy = vtopts = strdup(opts); 601 (void) strsep(&vtopts, ","); 602 603 /* 604 * Parse the list of options in the form 605 * key1=value1,...,keyN=valueN. 606 */ 607 while (vtopts != NULL) { 608 char *value = vtopts; 609 char *key; 610 611 key = strsep(&value, "="); 612 if (value == NULL) 613 break; 614 vtopts = value; 615 (void) strsep(&vtopts, ","); 616 617 if (strcmp(key, "mac") == 0) { 618 err = net_parsemac(value, sc->vsc_config.mac); 619 if (err) 620 break; 621 mac_provided = 1; 622 } else if (strcmp(key, "mtu") == 0) { 623 err = net_parsemtu(value, &mtu); 624 if (err) 625 break; 626 627 if (mtu < VTNET_MIN_MTU || mtu > VTNET_MAX_MTU) { 628 err = EINVAL; 629 errno = EINVAL; 630 break; 631 } 632 mtu_provided = 1; 633 } 634 } 635 636 free(optscopy); 637 638 if (err) { 639 free(sc); 640 return (err); 641 } 642 643 err = netbe_init(&sc->vsc_be, opts, pci_vtnet_rx_callback, 644 sc); 645 646 if (err) { 647 free(sc); 648 return (err); 649 } 650 sc->vsc_consts.vc_hv_caps |= VIRTIO_NET_F_MRG_RXBUF | 651 netbe_get_cap(sc->vsc_be); 652 } 653 654 if (!mac_provided) { 655 net_genmac(pi, sc->vsc_config.mac); 656 } 657 658 sc->vsc_config.mtu = mtu; 659 if (mtu_provided) { 660 sc->vsc_consts.vc_hv_caps |= VIRTIO_NET_F_MTU; 661 } 662 663 /* 664 * Since we do not actually support multiqueue, 665 * set the maximum virtqueue pairs to 1. 666 */ 667 sc->vsc_config.max_virtqueue_pairs = 1; 668 669 /* initialize config space */ 670 pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET); 671 pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); 672 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); 673 pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); 674 pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); 675 676 /* Link is up if we managed to open backend device. */ 677 sc->vsc_config.status = (opts == NULL || sc->vsc_be); 678 679 vi_softc_linkup(&sc->vsc_vs, &sc->vsc_consts, sc, pi, sc->vsc_queues); 680 sc->vsc_vs.vs_mtx = &sc->vsc_mtx; 681 682 /* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ 683 if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) { 684 free(sc); 685 return (1); 686 } 687 688 /* use BAR 0 to map config regs in IO space */ 689 vi_set_io_bar(&sc->vsc_vs, 0); 690 691 sc->resetting = 0; 692 693 sc->rx_merge = 0; 694 sc->vhdrlen = sizeof(struct virtio_net_rxhdr) - 2; 695 pthread_mutex_init(&sc->rx_mtx, NULL); 696 697 /* 698 * Initialize tx semaphore & spawn TX processing thread. 699 * As of now, only one thread for TX desc processing is 700 * spawned. 701 */ 702 sc->tx_in_progress = 0; 703 pthread_mutex_init(&sc->tx_mtx, NULL); 704 pthread_cond_init(&sc->tx_cond, NULL); 705 pthread_create(&sc->tx_tid, NULL, pci_vtnet_tx_thread, (void *)sc); 706 snprintf(tname, sizeof(tname), "vtnet-%d:%d tx", pi->pi_slot, 707 pi->pi_func); 708 pthread_set_name_np(sc->tx_tid, tname); 709 710 return (0); 711 } 712 713 static int 714 pci_vtnet_cfgwrite(void *vsc, int offset, int size, uint32_t value) 715 { 716 struct pci_vtnet_softc *sc = vsc; 717 void *ptr; 718 719 if (offset < (int)sizeof(sc->vsc_config.mac)) { 720 assert(offset + size <= (int)sizeof(sc->vsc_config.mac)); 721 /* 722 * The driver is allowed to change the MAC address 723 */ 724 ptr = &sc->vsc_config.mac[offset]; 725 memcpy(ptr, &value, size); 726 } else { 727 /* silently ignore other writes */ 728 DPRINTF(("vtnet: write to readonly reg %d", offset)); 729 } 730 731 return (0); 732 } 733 734 static int 735 pci_vtnet_cfgread(void *vsc, int offset, int size, uint32_t *retval) 736 { 737 struct pci_vtnet_softc *sc = vsc; 738 void *ptr; 739 740 ptr = (uint8_t *)&sc->vsc_config + offset; 741 memcpy(retval, ptr, size); 742 return (0); 743 } 744 745 static void 746 pci_vtnet_neg_features(void *vsc, uint64_t negotiated_features) 747 { 748 struct pci_vtnet_softc *sc = vsc; 749 750 sc->vsc_features = negotiated_features; 751 752 if (negotiated_features & VIRTIO_NET_F_MRG_RXBUF) { 753 sc->vhdrlen = sizeof(struct virtio_net_rxhdr); 754 sc->rx_merge = 1; 755 } else { 756 /* 757 * Without mergeable rx buffers, virtio-net header is 2 758 * bytes shorter than sizeof(struct virtio_net_rxhdr). 759 */ 760 sc->vhdrlen = sizeof(struct virtio_net_rxhdr) - 2; 761 sc->rx_merge = 0; 762 } 763 764 /* Tell the backend to enable some capabilities it has advertised. */ 765 netbe_set_cap(sc->vsc_be, negotiated_features, sc->vhdrlen); 766 sc->be_vhdrlen = netbe_get_vnet_hdr_len(sc->vsc_be); 767 assert(sc->be_vhdrlen == 0 || sc->be_vhdrlen == sc->vhdrlen); 768 769 pthread_mutex_lock(&sc->rx_mtx); 770 sc->features_negotiated = true; 771 pthread_mutex_unlock(&sc->rx_mtx); 772 } 773 774 #ifdef BHYVE_SNAPSHOT 775 static void 776 pci_vtnet_pause(void *vsc) 777 { 778 struct pci_vtnet_softc *sc = vsc; 779 780 DPRINTF(("vtnet: device pause requested !\n")); 781 782 /* Acquire the RX lock to block RX processing. */ 783 pthread_mutex_lock(&sc->rx_mtx); 784 785 /* Wait for the transmit thread to finish its processing. */ 786 pthread_mutex_lock(&sc->tx_mtx); 787 while (sc->tx_in_progress) { 788 pthread_mutex_unlock(&sc->tx_mtx); 789 usleep(10000); 790 pthread_mutex_lock(&sc->tx_mtx); 791 } 792 } 793 794 static void 795 pci_vtnet_resume(void *vsc) 796 { 797 struct pci_vtnet_softc *sc = vsc; 798 799 DPRINTF(("vtnet: device resume requested !\n")); 800 801 pthread_mutex_unlock(&sc->tx_mtx); 802 /* The RX lock should have been acquired in vtnet_pause. */ 803 pthread_mutex_unlock(&sc->rx_mtx); 804 } 805 806 static int 807 pci_vtnet_snapshot(void *vsc, struct vm_snapshot_meta *meta) 808 { 809 int ret; 810 struct pci_vtnet_softc *sc = vsc; 811 812 DPRINTF(("vtnet: device snapshot requested !\n")); 813 814 /* 815 * Queues and consts should have been saved by the more generic 816 * vi_pci_snapshot function. We need to save only our features and 817 * config. 818 */ 819 820 SNAPSHOT_VAR_OR_LEAVE(sc->vsc_features, meta, ret, done); 821 822 /* Force reapply negociated features at restore time */ 823 if (meta->op == VM_SNAPSHOT_RESTORE) { 824 pci_vtnet_neg_features(sc, sc->vsc_features); 825 netbe_rx_enable(sc->vsc_be); 826 } 827 828 SNAPSHOT_VAR_OR_LEAVE(sc->vsc_config, meta, ret, done); 829 SNAPSHOT_VAR_OR_LEAVE(sc->rx_merge, meta, ret, done); 830 831 SNAPSHOT_VAR_OR_LEAVE(sc->vhdrlen, meta, ret, done); 832 SNAPSHOT_VAR_OR_LEAVE(sc->be_vhdrlen, meta, ret, done); 833 834 done: 835 return (ret); 836 } 837 #endif 838 839 static struct pci_devemu pci_de_vnet = { 840 .pe_emu = "virtio-net", 841 .pe_init = pci_vtnet_init, 842 .pe_barwrite = vi_pci_write, 843 .pe_barread = vi_pci_read, 844 #ifdef BHYVE_SNAPSHOT 845 .pe_snapshot = vi_pci_snapshot, 846 .pe_pause = vi_pci_pause, 847 .pe_resume = vi_pci_resume, 848 #endif 849 }; 850 PCI_EMUL_SET(pci_de_vnet); 851