From owner-svn-src-all@freebsd.org Tue Nov 19 21:10:44 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id BB7D41BE20B; Tue, 19 Nov 2019 21:10:44 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47HdlS4XSmz3wy1; Tue, 19 Nov 2019 21:10:44 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7F32B1851A; Tue, 19 Nov 2019 21:10:44 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xAJLAilC092848; Tue, 19 Nov 2019 21:10:44 GMT (envelope-from vmaffione@FreeBSD.org) Received: (from vmaffione@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xAJLAi9Y092847; Tue, 19 Nov 2019 21:10:44 GMT (envelope-from vmaffione@FreeBSD.org) Message-Id: <201911192110.xAJLAi9Y092847@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: vmaffione set sender to vmaffione@FreeBSD.org using -f From: Vincenzo Maffione Date: Tue, 19 Nov 2019 21:10:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354864 - head/usr.sbin/bhyve X-SVN-Group: head X-SVN-Commit-Author: vmaffione X-SVN-Commit-Paths: head/usr.sbin/bhyve X-SVN-Commit-Revision: 354864 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Nov 2019 21:10:44 -0000 Author: vmaffione Date: Tue Nov 19 21:10:44 2019 New Revision: 354864 URL: https://svnweb.freebsd.org/changeset/base/354864 Log: bhyve: virtio-net: disable receive until features are negotiated This patch fixes a race condition where the receive callback is called while the device is being reset. Since the rx_merge variable may change during reset, the receive callback may operate inconsistently with what the guest expects. Also, get rid of the unused rx_vhdrlen variable. PR: 242023 Reported by: aleksandr.fedorov@itglobal.com Reviewed by: markj, jhb MFC with: r354552 Differential Revision: https://reviews.freebsd.org/D22440 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 Tue Nov 19 21:08:18 2019 (r354863) +++ head/usr.sbin/bhyve/pci_virtio_net.c Tue Nov 19 21:10:44 2019 (r354864) @@ -109,7 +109,6 @@ struct pci_vtnet_softc { uint64_t vsc_features; /* negotiated features */ pthread_mutex_t rx_mtx; - unsigned int rx_vhdrlen; int rx_merge; /* merged rx bufs in use */ pthread_t tx_tid; @@ -149,6 +148,16 @@ pci_vtnet_reset(void *vsc) /* Acquire the RX lock to block RX processing. */ pthread_mutex_lock(&sc->rx_mtx); + /* + * Make sure receive operation is disabled at least until we + * re-negotiate the features, since receive operation depends + * on the value of sc->rx_merge and the header length, which + * are both set in pci_vtnet_neg_features(). + * Receive operation will be enabled again once the guest adds + * the first receive buffers and kicks us. + */ + netbe_rx_disable(sc->vsc_be); + /* Set sc->resetting and give a chance to the TX thread to stop. */ pthread_mutex_lock(&sc->tx_mtx); sc->resetting = 1; @@ -158,9 +167,6 @@ pci_vtnet_reset(void *vsc) pthread_mutex_lock(&sc->tx_mtx); } - sc->rx_merge = 1; - sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); - /* * Now reset rings, MSI-X vectors, and negotiated capabilities. * Do that with the TX lock held, since we need to reset @@ -512,8 +518,7 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst * sc->resetting = 0; - sc->rx_merge = 1; - sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); + sc->rx_merge = 0; pthread_mutex_init(&sc->rx_mtx, NULL); /* @@ -568,18 +573,24 @@ static void pci_vtnet_neg_features(void *vsc, uint64_t negotiated_features) { struct pci_vtnet_softc *sc = vsc; + unsigned int rx_vhdrlen; sc->vsc_features = negotiated_features; - if (!(negotiated_features & VIRTIO_NET_F_MRG_RXBUF)) { + if (negotiated_features & VIRTIO_NET_F_MRG_RXBUF) { + rx_vhdrlen = sizeof(struct virtio_net_rxhdr); + sc->rx_merge = 1; + } else { + /* + * Without mergeable rx buffers, virtio-net header is 2 + * bytes shorter than sizeof(struct virtio_net_rxhdr). + */ + rx_vhdrlen = sizeof(struct virtio_net_rxhdr) - 2; sc->rx_merge = 0; - /* Without mergeable rx buffers, virtio-net header is 2 - * bytes shorter than sizeof(struct virtio_net_rxhdr). */ - sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr) - 2; } /* Tell the backend to enable some capabilities it has advertised. */ - netbe_set_cap(sc->vsc_be, negotiated_features, sc->rx_vhdrlen); + netbe_set_cap(sc->vsc_be, negotiated_features, rx_vhdrlen); } static struct pci_devemu pci_de_vnet = {