Commit 9207d47f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Jason Gunthorpe:

 - Several error unwind misses on system calls in mlx5, mana, ocrdma,
   vmw_pvrdma, mlx4, and hns

 - More rxe bugs processing network packets

 - User triggerable races in mlx5 when destroying and creating the same
   same object when the FW returns the same object ID

 - Incorrect passing of an IPv6 address through netlink
   RDMA_NL_LS_OP_IP_RESOLVE

 - Add memory ordering for mlx5's lock avoidance pattenr

 - Protect mana from kernel memory overflow

 - Use safe patterns for xarray/radix_tree look up in mlx5 and hns

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (24 commits)
  RDMA/hns: Fix unlocked call to hns_roce_qp_remove()
  RDMA/hns: Fix xarray race in hns_roce_create_qp_common()
  RDMA/hns: Fix xarray race in hns_roce_create_srq()
  RDMA/mlx4: Fix mis-use of RCU in mlx4_srq_event()
  RDMA/mlx4: Fix resource leak on error in mlx4_ib_create_srq()
  RDMA/vmw_pvrdma: Fix double free on pvrdma_alloc_ucontext() error path
  RDMA/ocrdma: Don't NULL deref uctx on errors in ocrdma_copy_pd_uresp()
  RDMA/ocrdma: Clarify the mm_head searching
  RDMA/mana: Fix error unwind in mana_ib_create_qp_rss()
  RDMA/mana: Fix mana_destroy_wq_obj() cleanup in mana_ib_create_qp_rss()
  RDMA/mana: Remove user triggerable WARN_ON() in mana_ib_create_qp_rss()
  RDMA/mana: Validate rx_hash_key_len
  RDMA/mlx5: Add missing store/release for lock elision pattern
  RDMA/mlx5: Restore zero-init to mlx5_ib_modify_qp() ucmd
  RDMA/ionic: Fix typo in format string
  RDMA/mlx5: Fix null-ptr-deref in Raw Packet QP creation
  RDMA/core: Fix rereg_mr use-after-free race
  IB/core: Fix IPv6 netlink message size in ib_nl_ip_send_msg()
  RDMA/mlx5: Fix UAF in DCT destroy due to race with create
  RDMA/mlx5: Fix UAF in SRQ destroy due to race with create
  ...
parents 4e386547 0c99acbc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ static int ib_nl_ip_send_msg(struct rdma_dev_addr *dev_addr,
		attrtype = RDMA_NLA_F_MANDATORY | LS_NLA_TYPE_IPV6;
	}

	len = nla_total_size(sizeof(size));
	len = nla_total_size(size);
	len += NLMSG_ALIGN(sizeof(*header));

	skb = nlmsg_new(len, GFP_KERNEL);
+7 −2
Original line number Diff line number Diff line
@@ -778,6 +778,7 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
	struct ib_pd *orig_pd;
	struct ib_pd *new_pd;
	struct ib_mr *new_mr;
	u32 lkey, rkey;

	ret = uverbs_request(attrs, &cmd, sizeof(cmd));
	if (ret)
@@ -846,6 +847,8 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
		new_mr->uobject = uobj;
		atomic_inc(&new_pd->usecnt);
		new_uobj->object = new_mr;
		lkey = new_mr->lkey;
		rkey = new_mr->rkey;

		rdma_restrack_new(&new_mr->res, RDMA_RESTRACK_MR);
		rdma_restrack_set_name(&new_mr->res, NULL);
@@ -871,11 +874,13 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
			mr->iova = cmd.hca_va;
			mr->length = cmd.length;
		}
		lkey = mr->lkey;
		rkey = mr->rkey;
	}

	memset(&resp, 0, sizeof(resp));
	resp.lkey      = mr->lkey;
	resp.rkey      = mr->rkey;
	resp.lkey = lkey;
	resp.rkey = rkey;

	ret = uverbs_response(attrs, &resp, sizeof(resp));

+4 −1
Original line number Diff line number Diff line
@@ -1942,13 +1942,16 @@ int pio_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls, u8 *vl_scontexts)

void free_pio_map(struct hfi1_devdata *dd)
{
	struct pio_vl_map *map;

	/* Free PIO map if allocated */
	if (rcu_access_pointer(dd->pio_map)) {
		spin_lock_irq(&dd->pio_map_lock);
		pio_map_free(rcu_access_pointer(dd->pio_map));
		map = rcu_access_pointer(dd->pio_map);
		RCU_INIT_POINTER(dd->pio_map, NULL);
		spin_unlock_irq(&dd->pio_map_lock);
		synchronize_rcu();
		pio_map_free(map);
	}
	kfree(dd->kernel_send_context);
	dd->kernel_send_context = NULL;
+3 −1
Original line number Diff line number Diff line
@@ -1255,6 +1255,7 @@ void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
{
	size_t i;
	struct sdma_engine *sde;
	struct sdma_vl_map *map;

	if (dd->sdma_pad_dma) {
		dma_free_coherent(&dd->pcidev->dev, SDMA_PAD,
@@ -1291,10 +1292,11 @@ void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
	}
	if (rcu_access_pointer(dd->sdma_map)) {
		spin_lock_irq(&dd->sde_map_lock);
		sdma_map_free(rcu_access_pointer(dd->sdma_map));
		map = rcu_access_pointer(dd->sdma_map);
		RCU_INIT_POINTER(dd->sdma_map, NULL);
		spin_unlock_irq(&dd->sde_map_lock);
		synchronize_rcu();
		sdma_map_free(map);
	}
	kfree(dd->per_sdma);
	dd->per_sdma = NULL;
+10 −3
Original line number Diff line number Diff line
@@ -47,8 +47,8 @@ static struct hns_roce_qp *hns_roce_qp_lookup(struct hns_roce_dev *hr_dev,

	xa_lock_irqsave(&hr_dev->qp_table_xa, flags);
	qp = __hns_roce_qp_lookup(hr_dev, qpn);
	if (qp)
		refcount_inc(&qp->refcount);
	if (qp && !refcount_inc_not_zero(&qp->refcount))
		qp = NULL;
	xa_unlock_irqrestore(&hr_dev->qp_table_xa, flags);

	if (!qp)
@@ -1171,6 +1171,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
	struct hns_roce_ib_create_qp_resp resp = {};
	struct ib_device *ibdev = &hr_dev->ib_dev;
	struct hns_roce_ib_create_qp ucmd = {};
	unsigned long flags;
	int ret;

	mutex_init(&hr_qp->mutex);
@@ -1251,13 +1252,19 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,

	hr_qp->ibqp.qp_num = hr_qp->qpn;
	hr_qp->event = hns_roce_ib_qp_event;
	refcount_set(&hr_qp->refcount, 1);
	init_completion(&hr_qp->free);
	refcount_set_release(&hr_qp->refcount, 1);

	return 0;

err_flow_ctrl:
	spin_lock_irqsave(&hr_dev->qp_list_lock, flags);
	hns_roce_lock_cqs(init_attr->send_cq ? to_hr_cq(init_attr->send_cq) : NULL,
			  init_attr->recv_cq ? to_hr_cq(init_attr->recv_cq) : NULL);
	hns_roce_qp_remove(hr_dev, hr_qp);
	hns_roce_unlock_cqs(init_attr->send_cq ? to_hr_cq(init_attr->send_cq) : NULL,
			    init_attr->recv_cq ? to_hr_cq(init_attr->recv_cq) : NULL);
	spin_unlock_irqrestore(&hr_dev->qp_list_lock, flags);
err_store:
	free_qpc(hr_dev, hr_qp);
err_qpc:
Loading