From: deraadt Date: Sat, 27 Nov 2021 16:25:40 +0000 (+0000) Subject: previous commit causes gcc to perform an unaligned access to the tcphdr X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=378d0f97349913dd56824997e127911214644d21;p=openbsd previous commit causes gcc to perform an unaligned access to the tcphdr (at least on sparc64) since it accesses the bitfield using an "int sized" instructions, rather than the minimally sized byte instruction. This is permitted by the language laywers who probably prefer we change the tcphdr in every packet. It is not clear how to convince gcc to avoid this behaviour, and a week of futzing hasn't found fast path solutions yet. In the meantime the tree may not be broken. --- diff --git a/sys/dev/pci/if_ixl.c b/sys/dev/pci/if_ixl.c index 75b6269a04a..6c91c12b3ca 100644 --- a/sys/dev/pci/if_ixl.c +++ b/sys/dev/pci/if_ixl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ixl.c,v 1.76 2021/11/09 09:26:18 jan Exp $ */ +/* $OpenBSD: if_ixl.c,v 1.77 2021/11/27 16:25:40 deraadt Exp $ */ /* * Copyright (c) 2013-2015, Intel Corporation @@ -82,10 +82,6 @@ #endif #include -#include -#include -#include -#include #include #include @@ -1392,7 +1388,6 @@ static int ixl_rxeof(struct ixl_softc *, struct ixl_rx_ring *); static void ixl_rxfill(struct ixl_softc *, struct ixl_rx_ring *); static void ixl_rxrefill(void *); static int ixl_rxrinfo(struct ixl_softc *, struct if_rxrinfo *); -static void ixl_rx_checksum(struct mbuf *, uint64_t); #if NKSTAT > 0 static void ixl_kstat_attach(struct ixl_softc *); @@ -1947,9 +1942,9 @@ ixl_attach(struct device *parent, struct device *self, void *aux) ifp->if_capabilities = IFCAP_VLAN_MTU; #if 0 ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; -#endif ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | - IFCAP_CSUM_UDPv4 | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6; + IFCAP_CSUM_UDPv4; +#endif ifmedia_init(&sc->sc_media, 0, ixl_media_change, ixl_media_status); @@ -2776,69 +2771,6 @@ ixl_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m) BUS_DMA_STREAMING | BUS_DMA_NOWAIT)); } -static void -ixl_tx_setup_offload(struct mbuf *mp, uint64_t *cmd) -{ - uint64_t ip_hdr_len; - int ipoff = ETHER_HDR_LEN; - uint8_t ipproto; - struct ip *ip; -#ifdef INET6 - struct ip6_hdr *ip6; -#endif - struct tcphdr *th; - struct mbuf *m; - - switch (ntohs(mtod(mp, struct ether_header *)->ether_type)) { - case ETHERTYPE_IP: - if (mp->m_pkthdr.len < ETHER_HDR_LEN + sizeof(*ip)) - return; - m = m_getptr(mp, ETHER_HDR_LEN, &ipoff); - KASSERT(m != NULL && m->m_len - ipoff >= sizeof(*ip)); - ip = (struct ip *)(m->m_data + ipoff); - - if (mp->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT) - *cmd |= IXL_TX_DESC_CMD_IIPT_IPV4_CSUM; - else - *cmd |= IXL_TX_DESC_CMD_IIPT_IPV4; - - ip_hdr_len = ip->ip_hl << 2; - ipproto = ip->ip_p; - break; -#ifdef INET6 - case ETHERTYPE_IPV6: - if (mp->m_pkthdr.len < ETHER_HDR_LEN + sizeof(*ip6)) - return; - m = m_getptr(mp, ETHER_HDR_LEN, &ipoff); - KASSERT(m != NULL && m->m_len - ipoff >= sizeof(*ip6)); - ip6 = (struct ip6_hdr *)(m->m_data + ipoff); - - *cmd |= IXL_TX_DESC_CMD_IIPT_IPV6; - - ip_hdr_len = sizeof(*ip6); - ipproto = ip6->ip6_nxt; - break; -#endif - default: - return; - } - - *cmd |= (ETHER_HDR_LEN >> 1) << IXL_TX_DESC_MACLEN_SHIFT; - *cmd |= (ip_hdr_len >> 2) << IXL_TX_DESC_IPLEN_SHIFT; - - if (ipproto == IPPROTO_TCP && m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT) { - th = (struct tcphdr *)(m->m_data + ipoff + ip_hdr_len); - - *cmd |= IXL_TX_DESC_CMD_L4T_EOFT_TCP; - *cmd |= (uint64_t)th->th_off << IXL_TX_DESC_L4LEN_SHIFT; - } - - if (ipproto == IPPROTO_UDP && m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) { - *cmd |= IXL_TX_DESC_CMD_L4T_EOFT_UDP; - *cmd |= (sizeof(struct udphdr) >> 2) << IXL_TX_DESC_L4LEN_SHIFT; - } -} - static void ixl_start(struct ifqueue *ifq) { @@ -2849,7 +2781,7 @@ ixl_start(struct ifqueue *ifq) struct ixl_tx_map *txm; bus_dmamap_t map; struct mbuf *m; - uint64_t cmd, off = 0; + uint64_t cmd; unsigned int prod, free, last, i; unsigned int mask; int post = 0; @@ -2896,15 +2828,12 @@ ixl_start(struct ifqueue *ifq) bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREWRITE); - ixl_tx_setup_offload(m, &off); - for (i = 0; i < map->dm_nsegs; i++) { txd = &ring[prod]; cmd = (uint64_t)map->dm_segs[i].ds_len << IXL_TX_DESC_BSIZE_SHIFT; cmd |= IXL_TX_DESC_DTYPE_DATA | IXL_TX_DESC_CMD_ICRC; - cmd |= off; htolem64(&txd->addr, map->dm_segs[i].ds_addr); htolem64(&txd->cmd, cmd); @@ -3261,7 +3190,6 @@ ixl_rxeof(struct ixl_softc *sc, struct ixl_rx_ring *rxr) m->m_pkthdr.csum_flags |= M_FLOWID; } - ixl_rx_checksum(m, word); ml_enqueue(&ml, m); } else { ifp->if_ierrors++; /* XXX */ @@ -3394,23 +3322,6 @@ ixl_rxrinfo(struct ixl_softc *sc, struct if_rxrinfo *ifri) return (rv); } -static void -ixl_rx_checksum(struct mbuf *m, uint64_t word) -{ - if (!ISSET(word, IXL_RX_DESC_L3L4P)) - return; - - if (ISSET(word, IXL_RX_DESC_IPE)) - return; - - m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK; - - if (ISSET(word, IXL_RX_DESC_L4E)) - return; - - m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK; -} - static int ixl_intr0(void *xsc) {