From nobody Wed Aug 17 20:16:15 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4M7K676DgKz4Z8j4; Wed, 17 Aug 2022 20:16:15 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4M7K675h6Xz3CGK; Wed, 17 Aug 2022 20:16:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660767375; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=v413WLrZyqaEVgNUAYnZu1u3XTKJFI7iDybFRxSvtj4=; b=RLFtrymJZf+K08YHAEgyIxjEEUrbVrE5p0omceOfc5IFQkqENbt8p1BwyLyoSD1BqmcaAR 6PzI0RtPv9dvnX4V7XUOKkrItyM0R7OHXEgc0TCJu6rxvulY6Qf2lybf37Nr1AY3dknxJj ajjxQk8MB8NgKIPOAxBi1jJMnGs14/C5CVDkgvPeasFKuskFq4H5S+pdHvNgCV9TPHV85l IgGKTbH5UyXKwtcxawOGOVOPXy1YQDnfhAmF1I71EFmFfOsSuBdXRrUXouA+eoODHbV3jM jfiqGq0/sF2v5Jb142Al8igOZet2Jz4Fj5QS7hc/89PFRLQPgoTkaWslCdpjpQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4M7K674NsBz132Z; Wed, 17 Aug 2022 20:16:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 27HKGFne027814; Wed, 17 Aug 2022 20:16:15 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 27HKGFPZ027813; Wed, 17 Aug 2022 20:16:15 GMT (envelope-from git) Date: Wed, 17 Aug 2022 20:16:15 GMT Message-Id: <202208172016.27HKGFPZ027813@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bryan Venteicher Subject: git: 926cedd9a071 - main - virtio_mmio: Improve V1 spec conformance List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bryanv X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 926cedd9a0713c8ed9ff340b09401847b8bfd62c Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660767375; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=v413WLrZyqaEVgNUAYnZu1u3XTKJFI7iDybFRxSvtj4=; b=Zt6lZd9rU85sH7J6vQaszL8lp3TacqZYrGzilDJLrm+/vXQUBa3G61SHPl2/boiLKZpmX5 WjbIarcXKLEFXl41zGYUkTcK8o1+E26NR3/TcJU7o9O70nTdNA/DVSWSVjfnsVS37wE/76 8G+T/zZUQj/pWxnMPJwpeyz0LpApPZi7nxybINw/vnZB0Pof7FDFriW1hX3JORH4hgwhDY u0+4UaX47WVGhExh4J4Pqny5Nx+x0K8tJ84ZjNWrnQOortChCEDI4PzX4m0oP7UfaLe7cC 6fI3dJiHgefM/TnrwZflsXKrlkZZ2wHrtHzwYRTmdQrTi6yZO4oNM17F04AsxQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1660767375; a=rsa-sha256; cv=none; b=wlnUE2llw26UtnyocMrmJ+bzbkWEaSMgiajh8qL/kb8ReJKDEdIBJABbtmOmtWFNFthl95 iW2r+f1wzagOhjjIDzMaWmRiR6g7/wxD/alsbCvxxlo2KaZkt1Pe2uEbj/KLdwoNseOqcB myTncXcd3BhQd91f71QUvdjc8RhW8aMqhcnq++Gmz5ZCV3Ts93mSXeAhkXIF4cpLnESDzN FJemaDamcgOJoiqqM+ZtJa3nEqqWlTshzfkVVijwxg5LPeE1x528wIzCpuCsf4P03BC4+k Cwtxw5djcVDyCJRcRhKk0iCWY5GEjy64ZmkX8puPDjhQLReN5FqS9PVuLcx7zQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by bryanv: URL: https://cgit.FreeBSD.org/src/commit/?id=926cedd9a0713c8ed9ff340b09401847b8bfd62c commit 926cedd9a0713c8ed9ff340b09401847b8bfd62c Author: Bryan Venteicher AuthorDate: 2022-08-17 20:15:04 +0000 Commit: Bryan Venteicher CommitDate: 2022-08-17 20:15:04 +0000 virtio_mmio: Improve V1 spec conformance Implement the virtio_bus_finalize_features method so the FEATURES_OK status bit is set. Implement the virtio_bus_config_generation method to ensure larger than 4-byte reads are consistent. Reviewed by: cperciva MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D36150 --- sys/dev/virtio/mmio/virtio_mmio.c | 87 +++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/sys/dev/virtio/mmio/virtio_mmio.c b/sys/dev/virtio/mmio/virtio_mmio.c index 5e17cf59a84a..e2164eb9e195 100644 --- a/sys/dev/virtio/mmio/virtio_mmio.c +++ b/sys/dev/virtio/mmio/virtio_mmio.c @@ -74,6 +74,7 @@ static void vtmmio_child_detached(device_t, device_t); static int vtmmio_read_ivar(device_t, device_t, int, uintptr_t *); static int vtmmio_write_ivar(device_t, device_t, int, uintptr_t); static uint64_t vtmmio_negotiate_features(device_t, uint64_t); +static int vtmmio_finalize_features(device_t); static int vtmmio_with_feature(device_t, uint64_t); static void vtmmio_set_virtqueue(struct vtmmio_softc *sc, struct virtqueue *vq, uint32_t size); @@ -85,9 +86,11 @@ static void vtmmio_poll(device_t); static int vtmmio_reinit(device_t, uint64_t); static void vtmmio_reinit_complete(device_t); static void vtmmio_notify_virtqueue(device_t, uint16_t, bus_size_t); +static int vtmmio_config_generation(device_t); static uint8_t vtmmio_get_status(device_t); static void vtmmio_set_status(device_t, uint8_t); static void vtmmio_read_dev_config(device_t, bus_size_t, void *, int); +static uint64_t vtmmio_read_dev_config_8(struct vtmmio_softc *, bus_size_t); static void vtmmio_write_dev_config(device_t, bus_size_t, const void *, int); static void vtmmio_describe_features(struct vtmmio_softc *, const char *, uint64_t); @@ -152,6 +155,7 @@ static device_method_t vtmmio_methods[] = { /* VirtIO bus interface. */ DEVMETHOD(virtio_bus_negotiate_features, vtmmio_negotiate_features), + DEVMETHOD(virtio_bus_finalize_features, vtmmio_finalize_features), DEVMETHOD(virtio_bus_with_feature, vtmmio_with_feature), DEVMETHOD(virtio_bus_alloc_virtqueues, vtmmio_alloc_virtqueues), DEVMETHOD(virtio_bus_setup_intr, vtmmio_setup_intr), @@ -160,6 +164,7 @@ static device_method_t vtmmio_methods[] = { DEVMETHOD(virtio_bus_reinit, vtmmio_reinit), DEVMETHOD(virtio_bus_reinit_complete, vtmmio_reinit_complete), DEVMETHOD(virtio_bus_notify_vq, vtmmio_notify_virtqueue), + DEVMETHOD(virtio_bus_config_generation, vtmmio_config_generation), DEVMETHOD(virtio_bus_read_device_config, vtmmio_read_dev_config), DEVMETHOD(virtio_bus_write_device_config, vtmmio_write_dev_config), @@ -461,6 +466,31 @@ vtmmio_negotiate_features(device_t dev, uint64_t child_features) return (features); } +static int +vtmmio_finalize_features(device_t dev) +{ + struct vtmmio_softc *sc; + uint8_t status; + + sc = device_get_softc(dev); + + if (sc->vtmmio_version > 1) { + /* + * Must re-read the status after setting it to verify the + * negotiated features were accepted by the device. + */ + vtmmio_set_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); + + status = vtmmio_get_status(dev); + if ((status & VIRTIO_CONFIG_S_FEATURES_OK) == 0) { + device_printf(dev, "desired features were not accepted\n"); + return (ENOTSUP); + } + } + + return (0); +} + static int vtmmio_with_feature(device_t dev, uint64_t feature) { @@ -540,8 +570,6 @@ vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs, vqx = &sc->vtmmio_vqs[idx]; info = &vq_info[idx]; - vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_SEL, idx); - vtmmio_select_virtqueue(sc, idx); size = vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX); @@ -605,7 +633,16 @@ vtmmio_reinit(device_t dev, uint64_t features) vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER); + /* + * TODO: Check that features are not added as to what was + * originally negotiated. + */ vtmmio_negotiate_features(dev, features); + error = vtmmio_finalize_features(dev); + if (error) { + device_printf(dev, "cannot finalize features during reinit\n"); + return (error); + } if (sc->vtmmio_version == 1) { vtmmio_write_config_4(sc, VIRTIO_MMIO_GUEST_PAGE_SIZE, @@ -639,6 +676,22 @@ vtmmio_notify_virtqueue(device_t dev, uint16_t queue, bus_size_t offset) vtmmio_write_config_4(sc, offset, queue); } +static int +vtmmio_config_generation(device_t dev) +{ + struct vtmmio_softc *sc; + uint32_t gen; + + sc = device_get_softc(dev); + + if (sc->vtmmio_version > 1) + gen = vtmmio_read_config_4(sc, VIRTIO_MMIO_CONFIG_GENERATION); + else + gen = 0; + + return (gen); +} + static uint8_t vtmmio_get_status(device_t dev) { @@ -670,7 +723,6 @@ vtmmio_read_dev_config(device_t dev, bus_size_t offset, bus_size_t off; uint8_t *d; int size; - uint64_t low32, high32; sc = device_get_softc(dev); off = VIRTIO_MMIO_CONFIG + offset; @@ -707,9 +759,7 @@ vtmmio_read_dev_config(device_t dev, bus_size_t offset, le32toh(vtmmio_read_config_4(sc, off)); break; case 8: - low32 = le32toh(vtmmio_read_config_4(sc, off)); - high32 = le32toh(vtmmio_read_config_4(sc, off + 4)); - *(uint64_t *)dst = (high32 << 32) | low32; + *(uint64_t *)dst = vtmmio_read_dev_config_8(sc, off); break; default: panic("%s: invalid length %d\n", __func__, length); @@ -735,6 +785,24 @@ vtmmio_read_dev_config(device_t dev, bus_size_t offset, } } +static uint64_t +vtmmio_read_dev_config_8(struct vtmmio_softc *sc, bus_size_t off) +{ + device_t dev; + int gen; + uint32_t val0, val1; + + dev = sc->dev; + + do { + gen = vtmmio_config_generation(dev); + val0 = le32toh(vtmmio_read_config_4(sc, off)); + val1 = le32toh(vtmmio_read_config_4(sc, off + 4)); + } while (gen != vtmmio_config_generation(dev)); + + return (((uint64_t) val1 << 32) | val0); +} + static void vtmmio_write_dev_config(device_t dev, bus_size_t offset, const void *src, int length) @@ -888,10 +956,11 @@ vtmmio_free_virtqueues(struct vtmmio_softc *sc) vqx = &sc->vtmmio_vqs[idx]; vtmmio_select_virtqueue(sc, idx); - if (sc->vtmmio_version == 1) - vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, 0); - else + if (sc->vtmmio_version > 1) { vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_READY, 0); + vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_READY); + } else + vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, 0); virtqueue_free(vqx->vtv_vq); vqx->vtv_vq = NULL;