From 96802e33aab0dbcd487ab8a63cd5ef47a3a860c6 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 17 Mar 2017 03:03:58 +0000 Subject: [PATCH] MFC 314382,314483-314485 314382 hyperv/hn: Simplify RNDIS packet data offset calculation. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D9699 314483 hyperv/hn: Simplify RNDIS packet total length calculation. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D9712 314484 hyperv/hn: Make sure that RNDIS packet message is at least 4B aligned. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D9713 314485 hyperv/hn: Misaligned chimney sending buffers should not be used Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D9714 git-svn-id: svn://svn.freebsd.org/base/stable/10@315437 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/dev/hyperv/netvsc/hn_nvs.c | 11 ++++++++--- sys/dev/hyperv/netvsc/hn_rndis.c | 17 +++++++++++++++-- sys/dev/hyperv/netvsc/if_hn.c | 14 +++++--------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hn_nvs.c b/sys/dev/hyperv/netvsc/hn_nvs.c index b4e9b1a5e..a33a82f1e 100644 --- a/sys/dev/hyperv/netvsc/hn_nvs.c +++ b/sys/dev/hyperv/netvsc/hn_nvs.c @@ -272,12 +272,17 @@ hn_nvs_conn_chim(struct hn_softc *sc) error = EIO; goto cleanup; } - if (sectsz == 0) { + if (sectsz == 0 || sectsz % sizeof(uint32_t) != 0) { /* * Can't use chimney sending buffer; done! */ - if_printf(sc->hn_ifp, "zero chimney sending buffer " - "section size\n"); + if (sectsz == 0) { + if_printf(sc->hn_ifp, "zero chimney sending buffer " + "section size\n"); + } else { + if_printf(sc->hn_ifp, "misaligned chimney sending " + "buffers, section size: %u\n", sectsz); + } sc->hn_chim_szmax = 0; sc->hn_chim_cnt = 0; sc->hn_flags |= HN_FLAG_CHIM_CONNECTED; diff --git a/sys/dev/hyperv/netvsc/hn_rndis.c b/sys/dev/hyperv/netvsc/hn_rndis.c index 1e83fe4d8..3052baa94 100644 --- a/sys/dev/hyperv/netvsc/hn_rndis.c +++ b/sys/dev/hyperv/netvsc/hn_rndis.c @@ -842,9 +842,22 @@ hn_rndis_init(struct hn_softc *sc) sc->hn_rndis_agg_pkts = comp->rm_pktmaxcnt; sc->hn_rndis_agg_align = 1U << comp->rm_align; + if (sc->hn_rndis_agg_align < sizeof(uint32_t)) { + /* + * The RNDIS packet messsage encap assumes that the RNDIS + * packet message is at least 4 bytes aligned. Fix up the + * alignment here, if the remote side sets the alignment + * too low. + */ + if_printf(sc->hn_ifp, "fixup RNDIS aggpkt align: %u -> %zu\n", + sc->hn_rndis_agg_align, sizeof(uint32_t)); + sc->hn_rndis_agg_align = sizeof(uint32_t); + } + if (bootverbose) { - if_printf(sc->hn_ifp, "RNDIS ver %u.%u, pktsz %u, pktcnt %u, " - "align %u\n", comp->rm_ver_major, comp->rm_ver_minor, + if_printf(sc->hn_ifp, "RNDIS ver %u.%u, " + "aggpkt size %u, aggpkt cnt %u, aggpkt align %u\n", + comp->rm_ver_major, comp->rm_ver_minor, sc->hn_rndis_agg_size, sc->hn_rndis_agg_pkts, sc->hn_rndis_agg_align); } diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c index 8e99eef59..83deecaa4 100644 --- a/sys/dev/hyperv/netvsc/if_hn.c +++ b/sys/dev/hyperv/netvsc/if_hn.c @@ -1773,12 +1773,6 @@ hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize, pi->rm_type = pi_type; pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET; - /* Data immediately follow per-packet-info. */ - pkt->rm_dataoffset += pi_size; - - /* Update RNDIS packet msg length */ - pkt->rm_len += pi_size; - return (pi->rm_data); } @@ -1920,8 +1914,8 @@ hn_encap(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd, } pkt->rm_type = REMOTE_NDIS_PACKET_MSG; - pkt->rm_len = sizeof(*pkt) + m_head->m_pkthdr.len; - pkt->rm_dataoffset = sizeof(*pkt); + pkt->rm_len = m_head->m_pkthdr.len; + pkt->rm_dataoffset = 0; pkt->rm_datalen = m_head->m_pkthdr.len; pkt->rm_oobdataoffset = 0; pkt->rm_oobdatalen = 0; @@ -1991,8 +1985,10 @@ hn_encap(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd, } pkt_hlen = pkt->rm_pktinfooffset + pkt->rm_pktinfolen; + /* Fixup RNDIS packet message total length */ + pkt->rm_len += pkt_hlen; /* Convert RNDIS packet message offsets */ - pkt->rm_dataoffset = hn_rndis_pktmsg_offset(pkt->rm_dataoffset); + pkt->rm_dataoffset = hn_rndis_pktmsg_offset(pkt_hlen); pkt->rm_pktinfooffset = hn_rndis_pktmsg_offset(pkt->rm_pktinfooffset); /* -- 2.45.0