diff --git a/lib/libbhyve/pci.c b/lib/libbhyve/pci.c --- a/lib/libbhyve/pci.c +++ b/lib/libbhyve/pci.c @@ -135,4 +135,13 @@ .legacy_config = netbe_legacy_config, .validate_hotplug_request = netbe_validate_hotplug_request }; + +static struct devinfo virtio_net_info = { + .name = "virtio-net", + .init_fds = netbe_init_fds, + .legacy_config = netbe_legacy_config, + .validate_hotplug_request = netbe_validate_hotplug_request +}; + DATA_SET(pci_devinfo, e1000_info); +DATA_SET(pci_devinfo, virtio_net_info); diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -518,6 +518,8 @@ .Bl -bullet .It e1000 +.It +virtio-net .El .Ss Network device backends .Sm off diff --git a/usr.sbin/bhyve/pci_virtio_net.c b/usr.sbin/bhyve/pci_virtio_net.c --- a/usr.sbin/bhyve/pci_virtio_net.c +++ b/usr.sbin/bhyve/pci_virtio_net.c @@ -586,6 +586,8 @@ if (value != NULL) { err = net_parsemac(value, sc->vsc_config.mac); if (err) { + nvlist_add_string(nvl, "error", + "failed to parse MAC address"); free(sc); return (err); } @@ -596,6 +598,7 @@ if (value != NULL) { err = net_parsemtu(value, &mtu); if (err) { + nvlist_add_string(nvl, "error", "failed to parse MTU"); free(sc); return (err); } @@ -603,6 +606,7 @@ if (mtu < VTNET_MIN_MTU || mtu > VTNET_MAX_MTU) { err = EINVAL; errno = EINVAL; + nvlist_add_string(nvl, "error", "invalid MTU value"); free(sc); return (err); } @@ -643,6 +647,7 @@ /* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) { + nvlist_add_string(nvl, "error", "failed to setup interrupts"); free(sc); return (1); } @@ -672,6 +677,27 @@ return (0); } +static int +pci_vtnet_teardown(struct pci_devinst *pi) +{ + struct pci_vtnet_softc *sc; + + sc = pi->pi_arg; + + pthread_cancel(sc->tx_tid); + pthread_join(sc->tx_tid, NULL); + pthread_cond_destroy(&sc->tx_cond); + pthread_mutex_destroy(&sc->tx_mtx); + pthread_mutex_destroy(&sc->rx_mtx); + pthread_mutex_destroy(&sc->vsc_mtx); + + if (sc->vsc_be != NULL) + netbe_cleanup(sc->vsc_be); + free(sc); + + return (0); +} + static int pci_vtnet_cfgwrite(void *vsc, int offset, int size, uint32_t value) { @@ -803,6 +829,7 @@ static const struct pci_devemu pci_de_vnet = { .pe_emu = "virtio-net", .pe_init = pci_vtnet_init, + .pe_teardown = pci_vtnet_teardown, .pe_legacy_config = netbe_legacy_config, .pe_barwrite = vi_pci_write, .pe_barread = vi_pci_read,