aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-20 18:22:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-20 18:22:30 -0400
commit1abd8a8f39cd9a2925149000056494523c85643a (patch)
treea205728bebc9ad149599a60781130540c3e568da
parentd8894a08d91e230c5af9eed3de80114c5aaa3ccf (diff)
parent375dc53d032fc11e98036b5f228ad13f7c5933f5 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe: "Here are eight fairly small fixes collected over the last two weeks. Regression and crashing bug fixes: - mlx4/5: Fixes for issues found from various checkers - A resource tracking and uverbs regression in the core code - qedr: NULL pointer regression found during testing - rxe: Various small bugs" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: IB/rxe: Fix missing completion for mem_reg work requests RDMA/core: Save kernel caller name when creating CQ using ib_create_cq() IB/uverbs: Fix ordering of ucontext check in ib_uverbs_write IB/mlx4: Fix an error handling path in 'mlx4_ib_rereg_user_mr()' RDMA/qedr: Fix NULL pointer dereference when running over iWARP without RDMA-CM IB/mlx5: Fix return value check in flow_counters_set_data() IB/mlx5: Fix memory leak in mlx5_ib_create_flow IB/rxe: avoid double kfree skb
-rw-r--r--drivers/infiniband/core/uverbs_main.c14
-rw-r--r--drivers/infiniband/core/verbs.c14
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c7
-rw-r--r--drivers/infiniband/hw/mlx5/main.c36
-rw-r--r--drivers/infiniband/hw/qedr/verbs.c3
-rw-r--r--drivers/infiniband/sw/rxe/rxe_req.c5
-rw-r--r--include/rdma/ib_verbs.h13
7 files changed, 59 insertions, 33 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 3ae2339dd27a..2094d136513d 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -736,10 +736,6 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
736 if (ret) 736 if (ret)
737 return ret; 737 return ret;
738 738
739 if (!file->ucontext &&
740 (command != IB_USER_VERBS_CMD_GET_CONTEXT || extended))
741 return -EINVAL;
742
743 if (extended) { 739 if (extended) {
744 if (count < (sizeof(hdr) + sizeof(ex_hdr))) 740 if (count < (sizeof(hdr) + sizeof(ex_hdr)))
745 return -EINVAL; 741 return -EINVAL;
@@ -759,6 +755,16 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
759 goto out; 755 goto out;
760 } 756 }
761 757
758 /*
759 * Must be after the ib_dev check, as once the RCU clears ib_dev ==
760 * NULL means ucontext == NULL
761 */
762 if (!file->ucontext &&
763 (command != IB_USER_VERBS_CMD_GET_CONTEXT || extended)) {
764 ret = -EINVAL;
765 goto out;
766 }
767
762 if (!verify_command_mask(ib_dev, command, extended)) { 768 if (!verify_command_mask(ib_dev, command, extended)) {
763 ret = -EOPNOTSUPP; 769 ret = -EOPNOTSUPP;
764 goto out; 770 goto out;
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 0b56828c1319..9d6beb948535 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -1562,11 +1562,12 @@ EXPORT_SYMBOL(ib_destroy_qp);
1562 1562
1563/* Completion queues */ 1563/* Completion queues */
1564 1564
1565struct ib_cq *ib_create_cq(struct ib_device *device, 1565struct ib_cq *__ib_create_cq(struct ib_device *device,
1566 ib_comp_handler comp_handler, 1566 ib_comp_handler comp_handler,
1567 void (*event_handler)(struct ib_event *, void *), 1567 void (*event_handler)(struct ib_event *, void *),
1568 void *cq_context, 1568 void *cq_context,
1569 const struct ib_cq_init_attr *cq_attr) 1569 const struct ib_cq_init_attr *cq_attr,
1570 const char *caller)
1570{ 1571{
1571 struct ib_cq *cq; 1572 struct ib_cq *cq;
1572 1573
@@ -1580,12 +1581,13 @@ struct ib_cq *ib_create_cq(struct ib_device *device,
1580 cq->cq_context = cq_context; 1581 cq->cq_context = cq_context;
1581 atomic_set(&cq->usecnt, 0); 1582 atomic_set(&cq->usecnt, 0);
1582 cq->res.type = RDMA_RESTRACK_CQ; 1583 cq->res.type = RDMA_RESTRACK_CQ;
1584 cq->res.kern_name = caller;
1583 rdma_restrack_add(&cq->res); 1585 rdma_restrack_add(&cq->res);
1584 } 1586 }
1585 1587
1586 return cq; 1588 return cq;
1587} 1589}
1588EXPORT_SYMBOL(ib_create_cq); 1590EXPORT_SYMBOL(__ib_create_cq);
1589 1591
1590int rdma_set_cq_moderation(struct ib_cq *cq, u16 cq_count, u16 cq_period) 1592int rdma_set_cq_moderation(struct ib_cq *cq, u16 cq_count, u16 cq_period)
1591{ 1593{
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index ed1f253faf97..c7c85c22e4e3 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -486,8 +486,11 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
486 } 486 }
487 487
488 if (flags & IB_MR_REREG_ACCESS) { 488 if (flags & IB_MR_REREG_ACCESS) {
489 if (ib_access_writable(mr_access_flags) && !mmr->umem->writable) 489 if (ib_access_writable(mr_access_flags) &&
490 return -EPERM; 490 !mmr->umem->writable) {
491 err = -EPERM;
492 goto release_mpt_entry;
493 }
491 494
492 err = mlx4_mr_hw_change_access(dev->dev, *pmpt_entry, 495 err = mlx4_mr_hw_change_access(dev->dev, *pmpt_entry,
493 convert_access(mr_access_flags)); 496 convert_access(mr_access_flags));
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index e52dd21519b4..e3e330f59c2c 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -3199,8 +3199,8 @@ static int flow_counters_set_data(struct ib_counters *ibcounters,
3199 if (!mcounters->hw_cntrs_hndl) { 3199 if (!mcounters->hw_cntrs_hndl) {
3200 mcounters->hw_cntrs_hndl = mlx5_fc_create( 3200 mcounters->hw_cntrs_hndl = mlx5_fc_create(
3201 to_mdev(ibcounters->device)->mdev, false); 3201 to_mdev(ibcounters->device)->mdev, false);
3202 if (!mcounters->hw_cntrs_hndl) { 3202 if (IS_ERR(mcounters->hw_cntrs_hndl)) {
3203 ret = -ENOMEM; 3203 ret = PTR_ERR(mcounters->hw_cntrs_hndl);
3204 goto free; 3204 goto free;
3205 } 3205 }
3206 hw_hndl = true; 3206 hw_hndl = true;
@@ -3546,29 +3546,35 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
3546 return ERR_PTR(-ENOMEM); 3546 return ERR_PTR(-ENOMEM);
3547 3547
3548 err = ib_copy_from_udata(ucmd, udata, required_ucmd_sz); 3548 err = ib_copy_from_udata(ucmd, udata, required_ucmd_sz);
3549 if (err) { 3549 if (err)
3550 kfree(ucmd); 3550 goto free_ucmd;
3551 return ERR_PTR(err);
3552 }
3553 } 3551 }
3554 3552
3555 if (flow_attr->priority > MLX5_IB_FLOW_LAST_PRIO) 3553 if (flow_attr->priority > MLX5_IB_FLOW_LAST_PRIO) {
3556 return ERR_PTR(-ENOMEM); 3554 err = -ENOMEM;
3555 goto free_ucmd;
3556 }
3557 3557
3558 if (domain != IB_FLOW_DOMAIN_USER || 3558 if (domain != IB_FLOW_DOMAIN_USER ||
3559 flow_attr->port > dev->num_ports || 3559 flow_attr->port > dev->num_ports ||
3560 (flow_attr->flags & ~(IB_FLOW_ATTR_FLAGS_DONT_TRAP | 3560 (flow_attr->flags & ~(IB_FLOW_ATTR_FLAGS_DONT_TRAP |
3561 IB_FLOW_ATTR_FLAGS_EGRESS))) 3561 IB_FLOW_ATTR_FLAGS_EGRESS))) {
3562 return ERR_PTR(-EINVAL); 3562 err = -EINVAL;
3563 goto free_ucmd;
3564 }
3563 3565
3564 if (is_egress && 3566 if (is_egress &&
3565 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT || 3567 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
3566 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) 3568 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
3567 return ERR_PTR(-EINVAL); 3569 err = -EINVAL;
3570 goto free_ucmd;
3571 }
3568 3572
3569 dst = kzalloc(sizeof(*dst), GFP_KERNEL); 3573 dst = kzalloc(sizeof(*dst), GFP_KERNEL);
3570 if (!dst) 3574 if (!dst) {
3571 return ERR_PTR(-ENOMEM); 3575 err = -ENOMEM;
3576 goto free_ucmd;
3577 }
3572 3578
3573 mutex_lock(&dev->flow_db->lock); 3579 mutex_lock(&dev->flow_db->lock);
3574 3580
@@ -3637,8 +3643,8 @@ destroy_ft:
3637unlock: 3643unlock:
3638 mutex_unlock(&dev->flow_db->lock); 3644 mutex_unlock(&dev->flow_db->lock);
3639 kfree(dst); 3645 kfree(dst);
3646free_ucmd:
3640 kfree(ucmd); 3647 kfree(ucmd);
3641 kfree(handler);
3642 return ERR_PTR(err); 3648 return ERR_PTR(err);
3643} 3649}
3644 3650
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index f7ac8fc9b531..f07b8df96f43 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -1957,6 +1957,9 @@ int qedr_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
1957 } 1957 }
1958 1958
1959 if (attr_mask & (IB_QP_AV | IB_QP_PATH_MTU)) { 1959 if (attr_mask & (IB_QP_AV | IB_QP_PATH_MTU)) {
1960 if (rdma_protocol_iwarp(&dev->ibdev, 1))
1961 return -EINVAL;
1962
1960 if (attr_mask & IB_QP_PATH_MTU) { 1963 if (attr_mask & IB_QP_PATH_MTU) {
1961 if (attr->path_mtu < IB_MTU_256 || 1964 if (attr->path_mtu < IB_MTU_256 ||
1962 attr->path_mtu > IB_MTU_4096) { 1965 attr->path_mtu > IB_MTU_4096) {
diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
index f30eeba3f772..8be27238a86e 100644
--- a/drivers/infiniband/sw/rxe/rxe_req.c
+++ b/drivers/infiniband/sw/rxe/rxe_req.c
@@ -645,6 +645,9 @@ next_wqe:
645 } else { 645 } else {
646 goto exit; 646 goto exit;
647 } 647 }
648 if ((wqe->wr.send_flags & IB_SEND_SIGNALED) ||
649 qp->sq_sig_type == IB_SIGNAL_ALL_WR)
650 rxe_run_task(&qp->comp.task, 1);
648 qp->req.wqe_index = next_index(qp->sq.queue, 651 qp->req.wqe_index = next_index(qp->sq.queue,
649 qp->req.wqe_index); 652 qp->req.wqe_index);
650 goto next_wqe; 653 goto next_wqe;
@@ -709,6 +712,7 @@ next_wqe:
709 712
710 if (fill_packet(qp, wqe, &pkt, skb, payload)) { 713 if (fill_packet(qp, wqe, &pkt, skb, payload)) {
711 pr_debug("qp#%d Error during fill packet\n", qp_num(qp)); 714 pr_debug("qp#%d Error during fill packet\n", qp_num(qp));
715 kfree_skb(skb);
712 goto err; 716 goto err;
713 } 717 }
714 718
@@ -740,7 +744,6 @@ next_wqe:
740 goto next_wqe; 744 goto next_wqe;
741 745
742err: 746err:
743 kfree_skb(skb);
744 wqe->status = IB_WC_LOC_PROT_ERR; 747 wqe->status = IB_WC_LOC_PROT_ERR;
745 wqe->state = wqe_state_error; 748 wqe->state = wqe_state_error;
746 __rxe_do_task(&qp->comp.task); 749 __rxe_do_task(&qp->comp.task);
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 4c6241bc2039..6c003995347a 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -3391,11 +3391,14 @@ int ib_process_cq_direct(struct ib_cq *cq, int budget);
3391 * 3391 *
3392 * Users can examine the cq structure to determine the actual CQ size. 3392 * Users can examine the cq structure to determine the actual CQ size.
3393 */ 3393 */
3394struct ib_cq *ib_create_cq(struct ib_device *device, 3394struct ib_cq *__ib_create_cq(struct ib_device *device,
3395 ib_comp_handler comp_handler, 3395 ib_comp_handler comp_handler,
3396 void (*event_handler)(struct ib_event *, void *), 3396 void (*event_handler)(struct ib_event *, void *),
3397 void *cq_context, 3397 void *cq_context,
3398 const struct ib_cq_init_attr *cq_attr); 3398 const struct ib_cq_init_attr *cq_attr,
3399 const char *caller);
3400#define ib_create_cq(device, cmp_hndlr, evt_hndlr, cq_ctxt, cq_attr) \
3401 __ib_create_cq((device), (cmp_hndlr), (evt_hndlr), (cq_ctxt), (cq_attr), KBUILD_MODNAME)
3399 3402
3400/** 3403/**
3401 * ib_resize_cq - Modifies the capacity of the CQ. 3404 * ib_resize_cq - Modifies the capacity of the CQ.