diff options
Diffstat (limited to 'drivers/infiniband/core')
| -rw-r--r-- | drivers/infiniband/core/cm.c | 1 | ||||
| -rw-r--r-- | drivers/infiniband/core/cma.c | 15 | ||||
| -rw-r--r-- | drivers/infiniband/core/core_priv.h | 14 | ||||
| -rw-r--r-- | drivers/infiniband/core/iwcm.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/core/nldev.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/core/rw.c | 31 | ||||
| -rw-r--r-- | drivers/infiniband/core/security.c | 14 | ||||
| -rw-r--r-- | drivers/infiniband/core/umem_odp.c | 24 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 9 | ||||
| -rw-r--r-- | drivers/infiniband/core/verbs.c | 10 | 
10 files changed, 79 insertions, 45 deletions
| diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 68cc1b2d6824..15e99a888427 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -1191,6 +1191,7 @@ struct ib_cm_id *ib_cm_insert_listen(struct ib_device *device,  			/* Sharing an ib_cm_id with different handlers is not  			 * supported */  			spin_unlock_irqrestore(&cm.lock, flags); +			ib_destroy_cm_id(cm_id);  			return ERR_PTR(-EINVAL);  		}  		refcount_inc(&cm_id_priv->refcount); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 72f032160c4b..2dec3a02ab9f 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -3212,19 +3212,26 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,  	int ret;  	id_priv = container_of(id, struct rdma_id_private, id); +	memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));  	if (id_priv->state == RDMA_CM_IDLE) {  		ret = cma_bind_addr(id, src_addr, dst_addr); -		if (ret) +		if (ret) { +			memset(cma_dst_addr(id_priv), 0, +			       rdma_addr_size(dst_addr));  			return ret; +		}  	} -	if (cma_family(id_priv) != dst_addr->sa_family) +	if (cma_family(id_priv) != dst_addr->sa_family) { +		memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));  		return -EINVAL; +	} -	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) +	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { +		memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));  		return -EINVAL; +	} -	memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));  	if (cma_any_addr(dst_addr)) {  		ret = cma_resolve_loopback(id_priv);  	} else { diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index b1457b3464d3..cf42acca4a3a 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -338,6 +338,20 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,  	qp->pd = pd;  	qp->uobject = uobj;  	qp->real_qp = qp; + +	qp->qp_type = attr->qp_type; +	qp->rwq_ind_tbl = attr->rwq_ind_tbl; +	qp->send_cq = attr->send_cq; +	qp->recv_cq = attr->recv_cq; +	qp->srq = attr->srq; +	qp->rwq_ind_tbl = attr->rwq_ind_tbl; +	qp->event_handler = attr->event_handler; + +	atomic_set(&qp->usecnt, 0); +	spin_lock_init(&qp->mr_lock); +	INIT_LIST_HEAD(&qp->rdma_mrs); +	INIT_LIST_HEAD(&qp->sig_mrs); +  	/*  	 * We don't track XRC QPs for now, because they don't have PD  	 * and more importantly they are created internaly by driver, diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index ade71823370f..da8adadf4755 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -159,8 +159,10 @@ static void dealloc_work_entries(struct iwcm_id_private *cm_id_priv)  {  	struct list_head *e, *tmp; -	list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) +	list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) { +		list_del(e);  		kfree(list_entry(e, struct iwcm_work, free_list)); +	}  }  static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count) diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index 37b433aa7306..e0b0a91da696 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c @@ -1757,6 +1757,8 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,  		if (ret)  			goto err_msg;  	} else { +		if (!tb[RDMA_NLDEV_ATTR_RES_LQPN]) +			goto err_msg;  		qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]);  		if (tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]) {  			cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); diff --git a/drivers/infiniband/core/rw.c b/drivers/infiniband/core/rw.c index 4fad732f9b3c..06e5b6787443 100644 --- a/drivers/infiniband/core/rw.c +++ b/drivers/infiniband/core/rw.c @@ -273,6 +273,23 @@ static int rdma_rw_init_single_wr(struct rdma_rw_ctx *ctx, struct ib_qp *qp,  	return 1;  } +static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg, +			     u32 sg_cnt, enum dma_data_direction dir) +{ +	if (is_pci_p2pdma_page(sg_page(sg))) +		pci_p2pdma_unmap_sg(dev->dma_device, sg, sg_cnt, dir); +	else +		ib_dma_unmap_sg(dev, sg, sg_cnt, dir); +} + +static int rdma_rw_map_sg(struct ib_device *dev, struct scatterlist *sg, +			  u32 sg_cnt, enum dma_data_direction dir) +{ +	if (is_pci_p2pdma_page(sg_page(sg))) +		return pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); +	return ib_dma_map_sg(dev, sg, sg_cnt, dir); +} +  /**   * rdma_rw_ctx_init - initialize a RDMA READ/WRITE context   * @ctx:	context to initialize @@ -295,11 +312,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,  	struct ib_device *dev = qp->pd->device;  	int ret; -	if (is_pci_p2pdma_page(sg_page(sg))) -		ret = pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); -	else -		ret = ib_dma_map_sg(dev, sg, sg_cnt, dir); - +	ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir);  	if (!ret)  		return -ENOMEM;  	sg_cnt = ret; @@ -338,7 +351,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,  	return ret;  out_unmap_sg: -	ib_dma_unmap_sg(dev, sg, sg_cnt, dir); +	rdma_rw_unmap_sg(dev, sg, sg_cnt, dir);  	return ret;  }  EXPORT_SYMBOL(rdma_rw_ctx_init); @@ -588,11 +601,7 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,  		break;  	} -	if (is_pci_p2pdma_page(sg_page(sg))) -		pci_p2pdma_unmap_sg(qp->pd->device->dma_device, sg, -				    sg_cnt, dir); -	else -		ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir); +	rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir);  }  EXPORT_SYMBOL(rdma_rw_ctx_destroy); diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c index 2b4d80393bd0..2d5608315dc8 100644 --- a/drivers/infiniband/core/security.c +++ b/drivers/infiniband/core/security.c @@ -340,15 +340,19 @@ static struct ib_ports_pkeys *get_new_pps(const struct ib_qp *qp,  		return NULL;  	if (qp_attr_mask & IB_QP_PORT) -		new_pps->main.port_num = -			(qp_pps) ? qp_pps->main.port_num : qp_attr->port_num; +		new_pps->main.port_num = qp_attr->port_num; +	else if (qp_pps) +		new_pps->main.port_num = qp_pps->main.port_num; +  	if (qp_attr_mask & IB_QP_PKEY_INDEX) -		new_pps->main.pkey_index = (qp_pps) ? qp_pps->main.pkey_index : -						      qp_attr->pkey_index; +		new_pps->main.pkey_index = qp_attr->pkey_index; +	else if (qp_pps) +		new_pps->main.pkey_index = qp_pps->main.pkey_index; +  	if ((qp_attr_mask & IB_QP_PKEY_INDEX) && (qp_attr_mask & IB_QP_PORT))  		new_pps->main.state = IB_PORT_PKEY_VALID; -	if (!(qp_attr_mask & (IB_QP_PKEY_INDEX || IB_QP_PORT)) && qp_pps) { +	if (!(qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) && qp_pps) {  		new_pps->main.port_num = qp_pps->main.port_num;  		new_pps->main.pkey_index = qp_pps->main.pkey_index;  		if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID) diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index b8c657b28380..cd656ad4953b 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -181,14 +181,28 @@ ib_umem_odp_alloc_child(struct ib_umem_odp *root, unsigned long addr,  	odp_data->page_shift = PAGE_SHIFT;  	odp_data->notifier.ops = ops; +	/* +	 * A mmget must be held when registering a notifier, the owming_mm only +	 * has a mm_grab at this point. +	 */ +	if (!mmget_not_zero(umem->owning_mm)) { +		ret = -EFAULT; +		goto out_free; +	} +  	odp_data->tgid = get_pid(root->tgid);  	ret = ib_init_umem_odp(odp_data, ops); -	if (ret) { -		put_pid(odp_data->tgid); -		kfree(odp_data); -		return ERR_PTR(ret); -	} +	if (ret) +		goto out_tgid; +	mmput(umem->owning_mm);  	return odp_data; + +out_tgid: +	put_pid(odp_data->tgid); +	mmput(umem->owning_mm); +out_free: +	kfree(odp_data); +	return ERR_PTR(ret);  }  EXPORT_SYMBOL(ib_umem_odp_alloc_child); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 025933752e1d..060b4ebbd2ba 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1445,16 +1445,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,  		if (ret)  			goto err_cb; -		qp->pd		  = pd; -		qp->send_cq	  = attr.send_cq; -		qp->recv_cq	  = attr.recv_cq; -		qp->srq		  = attr.srq; -		qp->rwq_ind_tbl	  = ind_tbl; -		qp->event_handler = attr.event_handler; -		qp->qp_type	  = attr.qp_type; -		atomic_set(&qp->usecnt, 0);  		atomic_inc(&pd->usecnt); -		qp->port = 0;  		if (attr.send_cq)  			atomic_inc(&attr.send_cq->usecnt);  		if (attr.recv_cq) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 3ebae3b65c28..e62c9dfc7837 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1185,16 +1185,6 @@ struct ib_qp *ib_create_qp_user(struct ib_pd *pd,  	if (ret)  		goto err; -	qp->qp_type    = qp_init_attr->qp_type; -	qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl; - -	atomic_set(&qp->usecnt, 0); -	qp->mrs_used = 0; -	spin_lock_init(&qp->mr_lock); -	INIT_LIST_HEAD(&qp->rdma_mrs); -	INIT_LIST_HEAD(&qp->sig_mrs); -	qp->port = 0; -  	if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {  		struct ib_qp *xrc_qp =  			create_xrc_qp_user(qp, qp_init_attr, udata); |