From 437cf2f1c5f05e34510f43e129af29a716b04ce6 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 3 Sep 2008 14:38:00 -0700 Subject: bnx2x: Accessing un-mapped page The allocated RX buffer size was 64 bytes bigger than the PCI mapped size with no good reason. If the packet was actually using the buffer up to its limit and if the last 64 bytes of the buffer crossed 4KB boundary then an unmapped PCI page was accessed. The fix is to use only one parameter for the buffer size - there is no need to differentiate between the buffer size and the PCI mapping size since the extra 64 bytes can actually be used by the FW to align the Ethernet payload to 64 bytes. Also updating the driver version and date Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 5 +++-- drivers/net/bnx2x_main.c | 34 +++++++++++++++++----------------- 2 files changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index a14dba1afcc..fd705d1295a 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -151,6 +151,8 @@ struct sw_rx_page { #define PAGES_PER_SGE_SHIFT 0 #define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT) +#define BCM_RX_ETH_PAYLOAD_ALIGN 64 + /* SGE ring related macros */ #define NUM_RX_SGE_PAGES 2 #define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge)) @@ -750,8 +752,7 @@ struct bnx2x { u32 rx_csum; u32 rx_offset; - u32 rx_buf_use_size; /* useable size */ - u32 rx_buf_size; /* with alignment */ + u32 rx_buf_size; #define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */ #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 82deea0a63f..a8eb3c4a47c 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -59,8 +59,8 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "1.45.20" -#define DRV_MODULE_RELDATE "2008/08/25" +#define DRV_MODULE_VERSION "1.45.21" +#define DRV_MODULE_RELDATE "2008/09/03" #define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung */ @@ -1027,7 +1027,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, if (unlikely(skb == NULL)) return -ENOMEM; - mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, + mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_size, PCI_DMA_FROMDEVICE); if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { dev_kfree_skb(skb); @@ -1169,7 +1169,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, /* move empty skb from pool to prod and map it */ prod_rx_buf->skb = fp->tpa_pool[queue].skb; mapping = pci_map_single(bp->pdev, fp->tpa_pool[queue].skb->data, - bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); + bp->rx_buf_size, PCI_DMA_FROMDEVICE); pci_unmap_addr_set(prod_rx_buf, mapping, mapping); /* move partial skb from cons to pool (don't unmap yet) */ @@ -1276,7 +1276,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, pool entry status to BNX2X_TPA_STOP even if new skb allocation fails. */ pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), - bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); + bp->rx_buf_size, PCI_DMA_FROMDEVICE); if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ @@ -1520,7 +1520,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) } else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) { pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), - bp->rx_buf_use_size, + bp->rx_buf_size, PCI_DMA_FROMDEVICE); skb_reserve(skb, pad); skb_put(skb, len); @@ -4229,7 +4229,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, if (fp->tpa_state[i] == BNX2X_TPA_START) pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), - bp->rx_buf_use_size, + bp->rx_buf_size, PCI_DMA_FROMDEVICE); dev_kfree_skb(skb); @@ -4245,15 +4245,14 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp) u16 ring_prod, cqe_ring_prod; int i, j; - bp->rx_buf_use_size = bp->dev->mtu; - bp->rx_buf_use_size += bp->rx_offset + ETH_OVREHEAD; - bp->rx_buf_size = bp->rx_buf_use_size + 64; + bp->rx_buf_size = bp->dev->mtu; + bp->rx_buf_size += bp->rx_offset + ETH_OVREHEAD + + BCM_RX_ETH_PAYLOAD_ALIGN; if (bp->flags & TPA_ENABLE_FLAG) { DP(NETIF_MSG_IFUP, - "rx_buf_use_size %d rx_buf_size %d effective_mtu %d\n", - bp->rx_buf_use_size, bp->rx_buf_size, - bp->dev->mtu + ETH_OVREHEAD); + "rx_buf_size %d effective_mtu %d\n", + bp->rx_buf_size, bp->dev->mtu + ETH_OVREHEAD); for_each_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; @@ -4462,9 +4461,10 @@ static void bnx2x_init_context(struct bnx2x *bp) context->ustorm_st_context.common.status_block_id = sb_id; context->ustorm_st_context.common.flags = USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT; - context->ustorm_st_context.common.mc_alignment_size = 64; + context->ustorm_st_context.common.mc_alignment_size = + BCM_RX_ETH_PAYLOAD_ALIGN; context->ustorm_st_context.common.bd_buff_size = - bp->rx_buf_use_size; + bp->rx_buf_size; context->ustorm_st_context.common.bd_page_base_hi = U64_HI(fp->rx_desc_mapping); context->ustorm_st_context.common.bd_page_base_lo = @@ -4717,7 +4717,7 @@ static void bnx2x_init_internal_func(struct bnx2x *bp) } /* Init CQ ring mapping and aggregation size */ - max_agg_size = min((u32)(bp->rx_buf_use_size + + max_agg_size = min((u32)(bp->rx_buf_size + 8*BCM_PAGE_SIZE*PAGES_PER_SGE), (u32)0xffff); for_each_queue(bp, i) { @@ -5940,7 +5940,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp) pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), - bp->rx_buf_use_size, + bp->rx_buf_size, PCI_DMA_FROMDEVICE); rx_buf->skb = NULL; -- cgit v1.2.3