summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/sfc/rx.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2013-11-28 18:58:11 (GMT)
committerBen Hutchings <bhutchings@solarflare.com>2013-12-12 22:07:12 (GMT)
commit2ccd0b192534b1dc6af45ffb81faa44b7ae416bf (patch)
tree297f8c256708bb77f60b3f4259dc5758f488826e /drivers/net/ethernet/sfc/rx.c
parent9ec0659595c8020f1efa55aa00870e8773f8ee89 (diff)
downloadlinux-2ccd0b192534b1dc6af45ffb81faa44b7ae416bf.tar.xz
sfc: Copy RX prefix into skb head area in efx_rx_mk_skb()
We can potentially pull the entire packet contents into the head area and then free the page it was in. In order to read an inline timestamp safely, we need to copy the prefix into the head area as well. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/rx.c')
-rw-r--r--drivers/net/ethernet/sfc/rx.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 8671bc1..d12abc5 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -476,14 +476,18 @@ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel,
struct sk_buff *skb;
/* Allocate an SKB to store the headers */
- skb = netdev_alloc_skb(efx->net_dev, hdr_len + EFX_PAGE_SKB_ALIGN);
+ skb = netdev_alloc_skb(efx->net_dev,
+ efx->rx_ip_align + efx->rx_prefix_size +
+ hdr_len);
if (unlikely(skb == NULL))
return NULL;
EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len);
- skb_reserve(skb, EFX_PAGE_SKB_ALIGN);
- memcpy(__skb_put(skb, hdr_len), eh, hdr_len);
+ memcpy(skb->data + efx->rx_ip_align, eh - efx->rx_prefix_size,
+ efx->rx_prefix_size + hdr_len);
+ skb_reserve(skb, efx->rx_ip_align + efx->rx_prefix_size);
+ __skb_put(skb, hdr_len);
/* Append the remaining page(s) onto the frag list */
if (rx_buf->len > hdr_len) {