aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/virtio_net.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fe4562d395e3..58ad40e17a74 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -483,7 +483,7 @@ xdp_xmit:
483 * anymore. 483 * anymore.
484 */ 484 */
485static struct page *xdp_linearize_page(struct receive_queue *rq, 485static struct page *xdp_linearize_page(struct receive_queue *rq,
486 u16 num_buf, 486 u16 *num_buf,
487 struct page *p, 487 struct page *p,
488 int offset, 488 int offset,
489 unsigned int *len) 489 unsigned int *len)
@@ -497,7 +497,7 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
497 memcpy(page_address(page) + page_off, page_address(p) + offset, *len); 497 memcpy(page_address(page) + page_off, page_address(p) + offset, *len);
498 page_off += *len; 498 page_off += *len;
499 499
500 while (--num_buf) { 500 while (--*num_buf) {
501 unsigned int buflen; 501 unsigned int buflen;
502 unsigned long ctx; 502 unsigned long ctx;
503 void *buf; 503 void *buf;
@@ -507,19 +507,22 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
507 if (unlikely(!ctx)) 507 if (unlikely(!ctx))
508 goto err_buf; 508 goto err_buf;
509 509
510 buf = mergeable_ctx_to_buf_address(ctx);
511 p = virt_to_head_page(buf);
512 off = buf - page_address(p);
513
510 /* guard against a misconfigured or uncooperative backend that 514 /* guard against a misconfigured or uncooperative backend that
511 * is sending packet larger than the MTU. 515 * is sending packet larger than the MTU.
512 */ 516 */
513 if ((page_off + buflen) > PAGE_SIZE) 517 if ((page_off + buflen) > PAGE_SIZE) {
518 put_page(p);
514 goto err_buf; 519 goto err_buf;
515 520 }
516 buf = mergeable_ctx_to_buf_address(ctx);
517 p = virt_to_head_page(buf);
518 off = buf - page_address(p);
519 521
520 memcpy(page_address(page) + page_off, 522 memcpy(page_address(page) + page_off,
521 page_address(p) + off, buflen); 523 page_address(p) + off, buflen);
522 page_off += buflen; 524 page_off += buflen;
525 put_page(p);
523 } 526 }
524 527
525 *len = page_off; 528 *len = page_off;
@@ -555,7 +558,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
555 /* This happens when rx buffer size is underestimated */ 558 /* This happens when rx buffer size is underestimated */
556 if (unlikely(num_buf > 1)) { 559 if (unlikely(num_buf > 1)) {
557 /* linearize data for XDP */ 560 /* linearize data for XDP */
558 xdp_page = xdp_linearize_page(rq, num_buf, 561 xdp_page = xdp_linearize_page(rq, &num_buf,
559 page, offset, &len); 562 page, offset, &len);
560 if (!xdp_page) 563 if (!xdp_page)
561 goto err_xdp; 564 goto err_xdp;