From ec30f0bec6985515768e4a5c0e242c560cc47783 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Sat, 27 Jul 2019 09:36:27 +0000 Subject: [PATCH] sfxge(4): fix power of 2 round up when align has smaller type Substitute driver-defined P2ROUNDUP() h with EFX_P2ROUNDUP() defined in libefx. Cast value and alignment to one specified type to guarantee result correctness. Reported by: Andrea Valsania Reviewed by: philip Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D21074 --- sys/dev/sfxge/common/ef10_impl.h | 9 +++++---- sys/dev/sfxge/common/ef10_nvram.c | 3 ++- sys/dev/sfxge/common/ef10_rx.c | 5 +++-- sys/dev/sfxge/common/efsys.h | 4 ---- sys/dev/sfxge/common/efx.h | 13 +++++++++---- sys/dev/sfxge/common/efx_mcdi.h | 9 ++++++--- sys/dev/sfxge/common/efx_tx.c | 4 ++-- sys/dev/sfxge/sfxge_port.c | 3 ++- sys/dev/sfxge/sfxge_rx.c | 7 ++++--- 9 files changed, 33 insertions(+), 24 deletions(-) diff --git a/sys/dev/sfxge/common/ef10_impl.h b/sys/dev/sfxge/common/ef10_impl.h index 3149fb51a14..06b3d6e06bb 100644 --- a/sys/dev/sfxge/common/ef10_impl.h +++ b/sys/dev/sfxge/common/ef10_impl.h @@ -1269,10 +1269,11 @@ efx_mcdi_set_nic_global( #define EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE 8 /* Minimum space for packet in packed stream mode */ -#define EFX_RX_PACKED_STREAM_MIN_PACKET_SPACE \ - P2ROUNDUP(EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE + \ - EFX_MAC_PDU_MIN + \ - EFX_RX_PACKED_STREAM_ALIGNMENT, \ +#define EFX_RX_PACKED_STREAM_MIN_PACKET_SPACE \ + EFX_P2ROUNDUP(size_t, \ + EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE + \ + EFX_MAC_PDU_MIN + \ + EFX_RX_PACKED_STREAM_ALIGNMENT, \ EFX_RX_PACKED_STREAM_ALIGNMENT) /* Maximum number of credits */ diff --git a/sys/dev/sfxge/common/ef10_nvram.c b/sys/dev/sfxge/common/ef10_nvram.c index dd6b595e56a..e37c4131f3f 100644 --- a/sys/dev/sfxge/common/ef10_nvram.c +++ b/sys/dev/sfxge/common/ef10_nvram.c @@ -394,7 +394,8 @@ tlv_write( if (len > 0) { ptr[(len - 1) / sizeof (uint32_t)] = 0; memcpy(ptr, data, len); - ptr += P2ROUNDUP(len, sizeof (uint32_t)) / sizeof (*ptr); + ptr += EFX_P2ROUNDUP(uint32_t, len, + sizeof (uint32_t)) / sizeof (*ptr); } return (ptr); diff --git a/sys/dev/sfxge/common/ef10_rx.c b/sys/dev/sfxge/common/ef10_rx.c index b61880ab31a..8f3043eac85 100644 --- a/sys/dev/sfxge/common/ef10_rx.c +++ b/sys/dev/sfxge/common/ef10_rx.c @@ -957,8 +957,9 @@ ef10_rx_qps_packet_info( *lengthp = EFX_QWORD_FIELD(*qwordp, ES_DZ_PS_RX_PREFIX_ORIG_LEN); buf_len = EFX_QWORD_FIELD(*qwordp, ES_DZ_PS_RX_PREFIX_CAP_LEN); - buf_len = P2ROUNDUP(buf_len + EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE, - EFX_RX_PACKED_STREAM_ALIGNMENT); + buf_len = EFX_P2ROUNDUP(uint16_t, + buf_len + EFX_RX_PACKED_STREAM_RX_PREFIX_SIZE, + EFX_RX_PACKED_STREAM_ALIGNMENT); *next_offsetp = current_offset + buf_len + EFX_RX_PACKED_STREAM_ALIGNMENT; diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h index 0c1c84cbb46..d22272fc503 100644 --- a/sys/dev/sfxge/common/efsys.h +++ b/sys/dev/sfxge/common/efsys.h @@ -88,10 +88,6 @@ extern "C" { #define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0) #endif -#ifndef P2ROUNDUP -#define P2ROUNDUP(x, align) (-(-(x) & -(align))) -#endif - #ifndef P2ALIGN #define P2ALIGN(_x, _a) ((_x) & -(_a)) #endif diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h index d9295b8070e..33f7c177ee6 100644 --- a/sys/dev/sfxge/common/efx.h +++ b/sys/dev/sfxge/common/efx.h @@ -56,6 +56,10 @@ extern "C" { /* The macro expands divider twice */ #define EFX_DIV_ROUND_UP(_n, _d) (((_n) + (_d) - 1) / (_d)) +/* Round value up to the nearest power of two. */ +#define EFX_P2ROUNDUP(_type, _value, _align) \ + (-(-(_type)(_value) & -(_type)(_align))) + /* Return codes */ typedef __success(return == 0) int efx_rc_t; @@ -522,10 +526,10 @@ typedef enum efx_link_mode_e { + /* bug16011 */ 16) \ #define EFX_MAC_PDU(_sdu) \ - P2ROUNDUP((_sdu) + EFX_MAC_PDU_ADJUSTMENT, 8) + EFX_P2ROUNDUP(size_t, (_sdu) + EFX_MAC_PDU_ADJUSTMENT, 8) /* - * Due to the P2ROUNDUP in EFX_MAC_PDU(), EFX_MAC_SDU_FROM_PDU() may give + * Due to the EFX_P2ROUNDUP in EFX_MAC_PDU(), EFX_MAC_SDU_FROM_PDU() may give * the SDU rounded up slightly. */ #define EFX_MAC_SDU_FROM_PDU(_pdu) ((_pdu) - EFX_MAC_PDU_ADJUSTMENT) @@ -611,8 +615,9 @@ efx_mac_stat_name( #define EFX_MAC_STATS_MASK_BITS_PER_PAGE (8 * sizeof (uint32_t)) -#define EFX_MAC_STATS_MASK_NPAGES \ - (P2ROUNDUP(EFX_MAC_NSTATS, EFX_MAC_STATS_MASK_BITS_PER_PAGE) / \ +#define EFX_MAC_STATS_MASK_NPAGES \ + (EFX_P2ROUNDUP(uint32_t, EFX_MAC_NSTATS, \ + EFX_MAC_STATS_MASK_BITS_PER_PAGE) / \ EFX_MAC_STATS_MASK_BITS_PER_PAGE) /* diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h index a2a89e852e8..4f75d9c726c 100644 --- a/sys/dev/sfxge/common/efx_mcdi.h +++ b/sys/dev/sfxge/common/efx_mcdi.h @@ -412,6 +412,11 @@ efx_mcdi_phy_module_get_info( (((mask) & (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) == \ (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) +#define EFX_MCDI_BUF_SIZE(_in_len, _out_len) \ + EFX_P2ROUNDUP(size_t, \ + MAX(MAX(_in_len, _out_len), (2 * sizeof (efx_dword_t))),\ + sizeof (efx_dword_t)) + /* * The buffer size must be a multiple of dword to ensure that MCDI works * properly with Siena based boards (which use on-chip buffer). Also, it @@ -419,9 +424,7 @@ efx_mcdi_phy_module_get_info( * error responses if the request/response buffer sizes are smaller. */ #define EFX_MCDI_DECLARE_BUF(_name, _in_len, _out_len) \ - uint8_t _name[P2ROUNDUP(MAX(MAX(_in_len, _out_len), \ - (2 * sizeof (efx_dword_t))), \ - sizeof (efx_dword_t))] = {0} + uint8_t _name[EFX_MCDI_BUF_SIZE(_in_len, _out_len)] = {0} typedef enum efx_mcdi_feature_id_e { EFX_MCDI_FEATURE_FW_UPDATE = 0, diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c index 503da9d9dc6..1b43363cb8a 100644 --- a/sys/dev/sfxge/common/efx_tx.c +++ b/sys/dev/sfxge/common/efx_tx.c @@ -797,7 +797,7 @@ siena_tx_qpost( * Fragments must not span 4k boundaries. * Here it is a stricter requirement than the maximum length. */ - EFSYS_ASSERT(P2ROUNDUP(start + 1, + EFSYS_ASSERT(EFX_P2ROUNDUP(efsys_dma_addr_t, start + 1, etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= end); EFX_TX_DESC(etp, start, size, ebp->eb_eop, added); @@ -1067,7 +1067,7 @@ siena_tx_qdesc_dma_create( * Fragments must not span 4k boundaries. * Here it is a stricter requirement than the maximum length. */ - EFSYS_ASSERT(P2ROUNDUP(addr + 1, + EFSYS_ASSERT(EFX_P2ROUNDUP(efsys_dma_addr_t, addr + 1, etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= addr + size); EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index, diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c index f6fbfea4028..08305a9b475 100644 --- a/sys/dev/sfxge/sfxge_port.c +++ b/sys/dev/sfxge/sfxge_port.c @@ -798,7 +798,8 @@ sfxge_port_init(struct sfxge_softc *sc) port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t), M_SFXGE, M_WAITOK | M_ZERO); mac_nstats = efx_nic_cfg_get(sc->enp)->enc_mac_stats_nstats; - mac_stats_size = P2ROUNDUP(mac_nstats * sizeof(uint64_t), EFX_BUF_SIZE); + mac_stats_size = EFX_P2ROUNDUP(size_t, mac_nstats * sizeof(uint64_t), + EFX_BUF_SIZE); if ((rc = sfxge_dma_alloc(sc, mac_stats_size, mac_stats_buf)) != 0) goto fail2; port->stats_update_period_ms = sfxge_port_stats_update_period_ms(sc); diff --git a/sys/dev/sfxge/sfxge_rx.c b/sys/dev/sfxge/sfxge_rx.c index 6371b234547..cb1caae8016 100644 --- a/sys/dev/sfxge/sfxge_rx.c +++ b/sys/dev/sfxge/sfxge_rx.c @@ -273,7 +273,8 @@ sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying) /* m_len specifies length of area to be mapped for DMA */ m->m_len = mblksize; - m->m_data = (caddr_t)P2ROUNDUP((uintptr_t)m->m_data, CACHE_LINE_SIZE); + m->m_data = (caddr_t)EFX_P2ROUNDUP(uintptr_t, m->m_data, + CACHE_LINE_SIZE); m->m_data += sc->rx_buffer_align; sfxge_map_mbuf_fast(rxq->mem.esm_tag, rxq->mem.esm_map, m, &seg); @@ -1103,14 +1104,14 @@ sfxge_rx_start(struct sfxge_softc *sc) /* Ensure IP headers are 32bit aligned */ hdrlen = sc->rx_prefix_size + sizeof (struct ether_header); - sc->rx_buffer_align = P2ROUNDUP(hdrlen, 4) - hdrlen; + sc->rx_buffer_align = EFX_P2ROUNDUP(size_t, hdrlen, 4) - hdrlen; sc->rx_buffer_size += sc->rx_buffer_align; /* Align end of packet buffer for RX DMA end padding */ align = MAX(1, encp->enc_rx_buf_align_end); EFSYS_ASSERT(ISP2(align)); - sc->rx_buffer_size = P2ROUNDUP(sc->rx_buffer_size, align); + sc->rx_buffer_size = EFX_P2ROUNDUP(size_t, sc->rx_buffer_size, align); /* * Standard mbuf zones only guarantee pointer-size alignment;