Date: Thu, 17 Dec 2020 16:52:40 +0000 (UTC) From: Aleksandr Fedorov <afedorov@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368720 - head/usr.sbin/bhyve Message-ID: <202012171652.0BHGqeor066457@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: afedorov Date: Thu Dec 17 16:52:40 2020 New Revision: 368720 URL: https://svnweb.freebsd.org/changeset/base/368720 Log: [bhyve] virtio-net: Do not allow receiving packets until features have been negotiated. Enforce the requirement that the RX callback cannot be called after a reset until the features have been negotiated. This fixes a race condition where the receive callback is called during a device reset. Reviewed by: vmaffione, grehan Approved by: vmaffione (mentor) Sponsored by: vstack.com Differential Revision: https://reviews.freebsd.org/D27381 Modified: head/usr.sbin/bhyve/pci_virtio_net.c Modified: head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- head/usr.sbin/bhyve/pci_virtio_net.c Thu Dec 17 15:00:19 2020 (r368719) +++ head/usr.sbin/bhyve/pci_virtio_net.c Thu Dec 17 16:52:40 2020 (r368720) @@ -111,6 +111,8 @@ struct pci_vtnet_softc { net_backend_t *vsc_be; + bool features_negotiated; /* protected by rx_mtx */ + int resetting; /* protected by tx_mtx */ uint64_t vsc_features; /* negotiated features */ @@ -176,6 +178,7 @@ pci_vtnet_reset(void *vsc) * Receive operation will be enabled again once the guest adds * the first receive buffers and kicks us. */ + sc->features_negotiated = false; netbe_rx_disable(sc->vsc_be); /* Set sc->resetting and give a chance to the TX thread to stop. */ @@ -246,6 +249,12 @@ pci_vtnet_rx(struct pci_vtnet_softc *sc) struct vqueue_info *vq; vq = &sc->vsc_queues[VTNET_RXQ]; + + /* Features must be negotiated */ + if (!sc->features_negotiated) { + return; + } + for (;;) { struct virtio_net_rxhdr *hdr; uint32_t riov_bytes; @@ -406,8 +415,14 @@ pci_vtnet_ping_rxq(void *vsc, struct vqueue_info *vq) /* * A qnotify means that the rx process can now begin. + * Enable RX only if features are negotiated. */ pthread_mutex_lock(&sc->rx_mtx); + if (!sc->features_negotiated) { + pthread_mutex_unlock(&sc->rx_mtx); + return; + } + vq_kick_disable(vq); netbe_rx_enable(sc->vsc_be); pthread_mutex_unlock(&sc->rx_mtx); @@ -750,6 +765,10 @@ pci_vtnet_neg_features(void *vsc, uint64_t negotiated_ netbe_set_cap(sc->vsc_be, negotiated_features, sc->vhdrlen); sc->be_vhdrlen = netbe_get_vnet_hdr_len(sc->vsc_be); assert(sc->be_vhdrlen == 0 || sc->be_vhdrlen == sc->vhdrlen); + + pthread_mutex_lock(&sc->rx_mtx); + sc->features_negotiated = true; + pthread_mutex_unlock(&sc->rx_mtx); } #ifdef BHYVE_SNAPSHOT
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012171652.0BHGqeor066457>