diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-12-21 10:46:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-12-21 10:46:08 -0500 |
commit | cd6a22310ec2a70092e136d0cd65bb77c1502521 (patch) | |
tree | c01fa788b27b240c7b426d7f329d92bd58c7b8f5 /net/rds/rdma.c | |
parent | 1e12a521d6917004f8b95a3b5864b92edc2694c8 (diff) | |
parent | 177c459b08a34dcf004aa9a4c1f1d8be682ff3af (diff) |
Merge USB 4.20-rc8 mergepoint into usb-next
We need the USB changes in here for additional patches to be able to
apply cleanly.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/rds/rdma.c')
-rw-r--r-- | net/rds/rdma.c | 75 |
1 files changed, 36 insertions, 39 deletions
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 98237feb607a..182ab8430594 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -517,9 +517,10 @@ static int rds_rdma_pages(struct rds_iovec iov[], int nr_iovecs) | |||
517 | return tot_pages; | 517 | return tot_pages; |
518 | } | 518 | } |
519 | 519 | ||
520 | int rds_rdma_extra_size(struct rds_rdma_args *args) | 520 | int rds_rdma_extra_size(struct rds_rdma_args *args, |
521 | struct rds_iov_vector *iov) | ||
521 | { | 522 | { |
522 | struct rds_iovec vec; | 523 | struct rds_iovec *vec; |
523 | struct rds_iovec __user *local_vec; | 524 | struct rds_iovec __user *local_vec; |
524 | int tot_pages = 0; | 525 | int tot_pages = 0; |
525 | unsigned int nr_pages; | 526 | unsigned int nr_pages; |
@@ -530,13 +531,23 @@ int rds_rdma_extra_size(struct rds_rdma_args *args) | |||
530 | if (args->nr_local == 0) | 531 | if (args->nr_local == 0) |
531 | return -EINVAL; | 532 | return -EINVAL; |
532 | 533 | ||
534 | iov->iov = kcalloc(args->nr_local, | ||
535 | sizeof(struct rds_iovec), | ||
536 | GFP_KERNEL); | ||
537 | if (!iov->iov) | ||
538 | return -ENOMEM; | ||
539 | |||
540 | vec = &iov->iov[0]; | ||
541 | |||
542 | if (copy_from_user(vec, local_vec, args->nr_local * | ||
543 | sizeof(struct rds_iovec))) | ||
544 | return -EFAULT; | ||
545 | iov->len = args->nr_local; | ||
546 | |||
533 | /* figure out the number of pages in the vector */ | 547 | /* figure out the number of pages in the vector */ |
534 | for (i = 0; i < args->nr_local; i++) { | 548 | for (i = 0; i < args->nr_local; i++, vec++) { |
535 | if (copy_from_user(&vec, &local_vec[i], | ||
536 | sizeof(struct rds_iovec))) | ||
537 | return -EFAULT; | ||
538 | 549 | ||
539 | nr_pages = rds_pages_in_vec(&vec); | 550 | nr_pages = rds_pages_in_vec(vec); |
540 | if (nr_pages == 0) | 551 | if (nr_pages == 0) |
541 | return -EINVAL; | 552 | return -EINVAL; |
542 | 553 | ||
@@ -558,15 +569,15 @@ int rds_rdma_extra_size(struct rds_rdma_args *args) | |||
558 | * Extract all arguments and set up the rdma_op | 569 | * Extract all arguments and set up the rdma_op |
559 | */ | 570 | */ |
560 | int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | 571 | int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, |
561 | struct cmsghdr *cmsg) | 572 | struct cmsghdr *cmsg, |
573 | struct rds_iov_vector *vec) | ||
562 | { | 574 | { |
563 | struct rds_rdma_args *args; | 575 | struct rds_rdma_args *args; |
564 | struct rm_rdma_op *op = &rm->rdma; | 576 | struct rm_rdma_op *op = &rm->rdma; |
565 | int nr_pages; | 577 | int nr_pages; |
566 | unsigned int nr_bytes; | 578 | unsigned int nr_bytes; |
567 | struct page **pages = NULL; | 579 | struct page **pages = NULL; |
568 | struct rds_iovec iovstack[UIO_FASTIOV], *iovs = iovstack; | 580 | struct rds_iovec *iovs; |
569 | int iov_size; | ||
570 | unsigned int i, j; | 581 | unsigned int i, j; |
571 | int ret = 0; | 582 | int ret = 0; |
572 | 583 | ||
@@ -586,31 +597,23 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | |||
586 | goto out_ret; | 597 | goto out_ret; |
587 | } | 598 | } |
588 | 599 | ||
589 | /* Check whether to allocate the iovec area */ | 600 | if (vec->len != args->nr_local) { |
590 | iov_size = args->nr_local * sizeof(struct rds_iovec); | 601 | ret = -EINVAL; |
591 | if (args->nr_local > UIO_FASTIOV) { | 602 | goto out_ret; |
592 | iovs = sock_kmalloc(rds_rs_to_sk(rs), iov_size, GFP_KERNEL); | ||
593 | if (!iovs) { | ||
594 | ret = -ENOMEM; | ||
595 | goto out_ret; | ||
596 | } | ||
597 | } | 603 | } |
598 | 604 | ||
599 | if (copy_from_user(iovs, (struct rds_iovec __user *)(unsigned long) args->local_vec_addr, iov_size)) { | 605 | iovs = vec->iov; |
600 | ret = -EFAULT; | ||
601 | goto out; | ||
602 | } | ||
603 | 606 | ||
604 | nr_pages = rds_rdma_pages(iovs, args->nr_local); | 607 | nr_pages = rds_rdma_pages(iovs, args->nr_local); |
605 | if (nr_pages < 0) { | 608 | if (nr_pages < 0) { |
606 | ret = -EINVAL; | 609 | ret = -EINVAL; |
607 | goto out; | 610 | goto out_ret; |
608 | } | 611 | } |
609 | 612 | ||
610 | pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); | 613 | pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); |
611 | if (!pages) { | 614 | if (!pages) { |
612 | ret = -ENOMEM; | 615 | ret = -ENOMEM; |
613 | goto out; | 616 | goto out_ret; |
614 | } | 617 | } |
615 | 618 | ||
616 | op->op_write = !!(args->flags & RDS_RDMA_READWRITE); | 619 | op->op_write = !!(args->flags & RDS_RDMA_READWRITE); |
@@ -620,11 +623,9 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | |||
620 | op->op_active = 1; | 623 | op->op_active = 1; |
621 | op->op_recverr = rs->rs_recverr; | 624 | op->op_recverr = rs->rs_recverr; |
622 | WARN_ON(!nr_pages); | 625 | WARN_ON(!nr_pages); |
623 | op->op_sg = rds_message_alloc_sgs(rm, nr_pages); | 626 | op->op_sg = rds_message_alloc_sgs(rm, nr_pages, &ret); |
624 | if (!op->op_sg) { | 627 | if (!op->op_sg) |
625 | ret = -ENOMEM; | 628 | goto out_pages; |
626 | goto out; | ||
627 | } | ||
628 | 629 | ||
629 | if (op->op_notify || op->op_recverr) { | 630 | if (op->op_notify || op->op_recverr) { |
630 | /* We allocate an uninitialized notifier here, because | 631 | /* We allocate an uninitialized notifier here, because |
@@ -635,7 +636,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | |||
635 | op->op_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL); | 636 | op->op_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL); |
636 | if (!op->op_notifier) { | 637 | if (!op->op_notifier) { |
637 | ret = -ENOMEM; | 638 | ret = -ENOMEM; |
638 | goto out; | 639 | goto out_pages; |
639 | } | 640 | } |
640 | op->op_notifier->n_user_token = args->user_token; | 641 | op->op_notifier->n_user_token = args->user_token; |
641 | op->op_notifier->n_status = RDS_RDMA_SUCCESS; | 642 | op->op_notifier->n_status = RDS_RDMA_SUCCESS; |
@@ -681,7 +682,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | |||
681 | */ | 682 | */ |
682 | ret = rds_pin_pages(iov->addr, nr, pages, !op->op_write); | 683 | ret = rds_pin_pages(iov->addr, nr, pages, !op->op_write); |
683 | if (ret < 0) | 684 | if (ret < 0) |
684 | goto out; | 685 | goto out_pages; |
685 | else | 686 | else |
686 | ret = 0; | 687 | ret = 0; |
687 | 688 | ||
@@ -714,13 +715,11 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, | |||
714 | nr_bytes, | 715 | nr_bytes, |
715 | (unsigned int) args->remote_vec.bytes); | 716 | (unsigned int) args->remote_vec.bytes); |
716 | ret = -EINVAL; | 717 | ret = -EINVAL; |
717 | goto out; | 718 | goto out_pages; |
718 | } | 719 | } |
719 | op->op_bytes = nr_bytes; | 720 | op->op_bytes = nr_bytes; |
720 | 721 | ||
721 | out: | 722 | out_pages: |
722 | if (iovs != iovstack) | ||
723 | sock_kfree_s(rds_rs_to_sk(rs), iovs, iov_size); | ||
724 | kfree(pages); | 723 | kfree(pages); |
725 | out_ret: | 724 | out_ret: |
726 | if (ret) | 725 | if (ret) |
@@ -838,11 +837,9 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, | |||
838 | rm->atomic.op_silent = !!(args->flags & RDS_RDMA_SILENT); | 837 | rm->atomic.op_silent = !!(args->flags & RDS_RDMA_SILENT); |
839 | rm->atomic.op_active = 1; | 838 | rm->atomic.op_active = 1; |
840 | rm->atomic.op_recverr = rs->rs_recverr; | 839 | rm->atomic.op_recverr = rs->rs_recverr; |
841 | rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1); | 840 | rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1, &ret); |
842 | if (!rm->atomic.op_sg) { | 841 | if (!rm->atomic.op_sg) |
843 | ret = -ENOMEM; | ||
844 | goto err; | 842 | goto err; |
845 | } | ||
846 | 843 | ||
847 | /* verify 8 byte-aligned */ | 844 | /* verify 8 byte-aligned */ |
848 | if (args->local_addr & 0x7) { | 845 | if (args->local_addr & 0x7) { |