|
@@ -1150,7 +1150,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
|
|
|
struct virtio_net_hdr_mrg_rxbuf *hdr;
|
|
|
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
|
|
|
struct virtnet_info *vi = sq->vq->vdev->priv;
|
|
|
- unsigned num_sg;
|
|
|
+ int num_sg;
|
|
|
unsigned hdr_len = vi->hdr_len;
|
|
|
bool can_push;
|
|
|
|
|
@@ -1177,11 +1177,16 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
|
|
|
if (can_push) {
|
|
|
__skb_push(skb, hdr_len);
|
|
|
num_sg = skb_to_sgvec(skb, sq->sg, 0, skb->len);
|
|
|
+ if (unlikely(num_sg < 0))
|
|
|
+ return num_sg;
|
|
|
/* Pull header back to avoid skew in tx bytes calculations. */
|
|
|
__skb_pull(skb, hdr_len);
|
|
|
} else {
|
|
|
sg_set_buf(sq->sg, hdr, hdr_len);
|
|
|
- num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1;
|
|
|
+ num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len);
|
|
|
+ if (unlikely(num_sg < 0))
|
|
|
+ return num_sg;
|
|
|
+ num_sg++;
|
|
|
}
|
|
|
return virtqueue_add_outbuf(sq->vq, sq->sg, num_sg, skb, GFP_ATOMIC);
|
|
|
}
|