diff options
Diffstat (limited to 'drivers/net/xen-netfront.c')
| -rw-r--r-- | drivers/net/xen-netfront.c | 15 | 
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 96ccd4e943db..e17879dd5d5a 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -565,6 +565,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)  	struct netfront_queue *queue = NULL;  	unsigned int num_queues = dev->real_num_tx_queues;  	u16 queue_index; +	struct sk_buff *nskb;  	/* Drop the packet if no queues are set up */  	if (num_queues < 1) @@ -593,6 +594,20 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)  	page = virt_to_page(skb->data);  	offset = offset_in_page(skb->data); + +	/* The first req should be at least ETH_HLEN size or the packet will be +	 * dropped by netback. +	 */ +	if (unlikely(PAGE_SIZE - offset < ETH_HLEN)) { +		nskb = skb_copy(skb, GFP_ATOMIC); +		if (!nskb) +			goto drop; +		dev_kfree_skb_any(skb); +		skb = nskb; +		page = virt_to_page(skb->data); +		offset = offset_in_page(skb->data); +	} +  	len = skb_headlen(skb);  	spin_lock_irqsave(&queue->tx_lock, flags);  |