diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/infiniband/core | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/infiniband/core')
| -rw-r--r-- | drivers/infiniband/core/cm.c | 3 | ||||
| -rw-r--r-- | drivers/infiniband/core/cma.c | 70 | ||||
| -rw-r--r-- | drivers/infiniband/core/user_mad.c | 27 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 7 | ||||
| -rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 14 | ||||
| -rw-r--r-- | drivers/infiniband/core/verbs.c | 2 | 
6 files changed, 70 insertions, 53 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 603c0aecc361..ff58058aeadc 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -2912,6 +2912,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,  	    (ari && ari_length > IB_CM_REJ_ARI_LENGTH))  		return -EINVAL; +	trace_icm_send_rej(&cm_id_priv->id, reason); +  	switch (state) {  	case IB_CM_REQ_SENT:  	case IB_CM_MRA_REQ_RCVD: @@ -2942,7 +2944,6 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,  		return -EINVAL;  	} -	trace_icm_send_rej(&cm_id_priv->id, reason);  	ret = ib_post_send_mad(msg, NULL);  	if (ret) {  		cm_free_msg(msg); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 308155937713..6b3f4384e46a 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -624,22 +624,11 @@ static inline unsigned short cma_family(struct rdma_id_private *id_priv)  	return id_priv->id.route.addr.src_addr.ss_family;  } -static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey) +static int cma_set_default_qkey(struct rdma_id_private *id_priv)  {  	struct ib_sa_mcmember_rec rec;  	int ret = 0; -	if (id_priv->qkey) { -		if (qkey && id_priv->qkey != qkey) -			return -EINVAL; -		return 0; -	} - -	if (qkey) { -		id_priv->qkey = qkey; -		return 0; -	} -  	switch (id_priv->id.ps) {  	case RDMA_PS_UDP:  	case RDMA_PS_IB: @@ -659,6 +648,16 @@ static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)  	return ret;  } +static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey) +{ +	if (!qkey || +	    (id_priv->qkey && (id_priv->qkey != qkey))) +		return -EINVAL; + +	id_priv->qkey = qkey; +	return 0; +} +  static void cma_translate_ib(struct sockaddr_ib *sib, struct rdma_dev_addr *dev_addr)  {  	dev_addr->dev_type = ARPHRD_INFINIBAND; @@ -710,8 +709,7 @@ cma_validate_port(struct ib_device *device, u32 port,  	}  	sgid_attr = rdma_find_gid_by_port(device, gid, gid_type, port, ndev); -	if (ndev) -		dev_put(ndev); +	dev_put(ndev);  	return sgid_attr;  } @@ -1229,7 +1227,7 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,  	*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;  	if (id_priv->id.qp_type == IB_QPT_UD) { -		ret = cma_set_qkey(id_priv, 0); +		ret = cma_set_default_qkey(id_priv);  		if (ret)  			return ret; @@ -2430,8 +2428,7 @@ err_unlock:  	mutex_unlock(&listen_id->handler_mutex);  net_dev_put: -	if (net_dev) -		dev_put(net_dev); +	dev_put(net_dev);  	return ret;  } @@ -3298,7 +3295,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)  	route->path_rec->traffic_class = tos;  	route->path_rec->mtu = iboe_get_mtu(ndev->mtu);  	route->path_rec->rate_selector = IB_SA_EQ; -	route->path_rec->rate = iboe_get_rate(ndev); +	route->path_rec->rate = IB_RATE_PORT_CURRENT;  	dev_put(ndev);  	route->path_rec->packet_life_time_selector = IB_SA_EQ;  	/* In case ACK timeout is set, use this value to calculate @@ -4569,7 +4566,10 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,  	memset(&rep, 0, sizeof rep);  	rep.status = status;  	if (status == IB_SIDR_SUCCESS) { -		ret = cma_set_qkey(id_priv, qkey); +		if (qkey) +			ret = cma_set_qkey(id_priv, qkey); +		else +			ret = cma_set_default_qkey(id_priv);  		if (ret)  			return ret;  		rep.qp_num = id_priv->qp_num; @@ -4774,9 +4774,7 @@ static void cma_make_mc_event(int status, struct rdma_id_private *id_priv,  	enum ib_gid_type gid_type;  	struct net_device *ndev; -	if (!status) -		status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey)); -	else +	if (status)  		pr_debug_ratelimited("RDMA CM: MULTICAST_ERROR: failed to join multicast. status %d\n",  				     status); @@ -4804,7 +4802,7 @@ static void cma_make_mc_event(int status, struct rdma_id_private *id_priv,  	}  	event->param.ud.qp_num = 0xFFFFFF; -	event->param.ud.qkey = be32_to_cpu(multicast->rec.qkey); +	event->param.ud.qkey = id_priv->qkey;  out:  	if (ndev) @@ -4823,8 +4821,11 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)  	    READ_ONCE(id_priv->state) == RDMA_CM_DESTROYING)  		goto out; -	cma_make_mc_event(status, id_priv, multicast, &event, mc); -	ret = cma_cm_event_handler(id_priv, &event); +	ret = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey)); +	if (!ret) { +		cma_make_mc_event(status, id_priv, multicast, &event, mc); +		ret = cma_cm_event_handler(id_priv, &event); +	}  	rdma_destroy_ah_attr(&event.param.ud.ah_attr);  	WARN_ON(ret); @@ -4877,9 +4878,11 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,  	if (ret)  		return ret; -	ret = cma_set_qkey(id_priv, 0); -	if (ret) -		return ret; +	if (!id_priv->qkey) { +		ret = cma_set_default_qkey(id_priv); +		if (ret) +			return ret; +	}  	cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid);  	rec.qkey = cpu_to_be32(id_priv->qkey); @@ -4956,15 +4959,12 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,  	cma_iboe_set_mgid(addr, &ib.rec.mgid, gid_type);  	ib.rec.pkey = cpu_to_be16(0xffff); -	if (id_priv->id.ps == RDMA_PS_UDP) -		ib.rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); -  	if (dev_addr->bound_dev_if)  		ndev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if);  	if (!ndev)  		return -ENODEV; -	ib.rec.rate = iboe_get_rate(ndev); +	ib.rec.rate = IB_RATE_PORT_CURRENT;  	ib.rec.hop_limit = 1;  	ib.rec.mtu = iboe_get_mtu(ndev->mtu); @@ -4984,6 +4984,9 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,  	if (err || !ib.rec.mtu)  		return err ?: -EINVAL; +	if (!id_priv->qkey) +		cma_set_default_qkey(id_priv); +  	rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,  		    &ib.rec.port_gid);  	INIT_WORK(&mc->iboe_join.work, cma_iboe_join_work_handler); @@ -5009,6 +5012,9 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,  			    READ_ONCE(id_priv->state) != RDMA_CM_ADDR_RESOLVED))  		return -EINVAL; +	if (id_priv->id.qp_type != IB_QPT_UD) +		return -EINVAL; +  	mc = kzalloc(sizeof(*mc), GFP_KERNEL);  	if (!mc)  		return -ENOMEM; diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index f83954180a33..7e5c33aad161 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -131,6 +131,11 @@ struct ib_umad_packet {  	struct ib_user_mad mad;  }; +struct ib_rmpp_mad_hdr { +	struct ib_mad_hdr	mad_hdr; +	struct ib_rmpp_hdr      rmpp_hdr; +} __packed; +  #define CREATE_TRACE_POINTS  #include <trace/events/ib_umad.h> @@ -494,11 +499,11 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,  			     size_t count, loff_t *pos)  {  	struct ib_umad_file *file = filp->private_data; +	struct ib_rmpp_mad_hdr *rmpp_mad_hdr;  	struct ib_umad_packet *packet;  	struct ib_mad_agent *agent;  	struct rdma_ah_attr ah_attr;  	struct ib_ah *ah; -	struct ib_rmpp_mad *rmpp_mad;  	__be64 *tid;  	int ret, data_len, hdr_len, copy_offset, rmpp_active;  	u8 base_version; @@ -506,7 +511,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,  	if (count < hdr_size(file) + IB_MGMT_RMPP_HDR)  		return -EINVAL; -	packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); +	packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL);  	if (!packet)  		return -ENOMEM; @@ -560,13 +565,13 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,  		goto err_up;  	} -	rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; -	hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); +	rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data; +	hdr_len = ib_get_mad_data_offset(rmpp_mad_hdr->mad_hdr.mgmt_class); -	if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) +	if (ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class)  	    && ib_mad_kernel_rmpp_agent(agent)) {  		copy_offset = IB_MGMT_RMPP_HDR; -		rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & +		rmpp_active = ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) &  						IB_MGMT_RMPP_FLAG_ACTIVE;  	} else {  		copy_offset = IB_MGMT_MAD_HDR; @@ -615,12 +620,12 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,  		tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;  		*tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |  				   (be64_to_cpup(tid) & 0xffffffff)); -		rmpp_mad->mad_hdr.tid = *tid; +		rmpp_mad_hdr->mad_hdr.tid = *tid;  	}  	if (!ib_mad_kernel_rmpp_agent(agent) -	   && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) -	   && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { +	    && ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class) +	    && (ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {  		spin_lock_irq(&file->send_lock);  		list_add_tail(&packet->list, &file->send_list);  		spin_unlock_irq(&file->send_lock); @@ -1229,8 +1234,8 @@ static char *umad_devnode(const struct device *dev, umode_t *mode)  	return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));  } -static ssize_t abi_version_show(struct class *class, -				struct class_attribute *attr, char *buf) +static ssize_t abi_version_show(const struct class *class, +				const struct class_attribute *attr, char *buf)  {  	return sysfs_emit(buf, "%d\n", IB_USER_MAD_ABI_VERSION);  } diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 4796f6a8828c..e836c9c477f6 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1850,8 +1850,13 @@ static int modify_qp(struct uverbs_attr_bundle *attrs,  		attr->path_mtu = cmd->base.path_mtu;  	if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)  		attr->path_mig_state = cmd->base.path_mig_state; -	if (cmd->base.attr_mask & IB_QP_QKEY) +	if (cmd->base.attr_mask & IB_QP_QKEY) { +		if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) { +			ret = -EPERM; +			goto release_qp; +		}  		attr->qkey = cmd->base.qkey; +	}  	if (cmd->base.attr_mask & IB_QP_RQ_PSN)  		attr->rq_psn = cmd->base.rq_psn;  	if (cmd->base.attr_mask & IB_QP_SQ_PSN) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index bdb179a09d77..7c9c79c13941 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -222,8 +222,12 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,  	spin_lock_irq(&ev_queue->lock);  	while (list_empty(&ev_queue->event_list)) { -		spin_unlock_irq(&ev_queue->lock); +		if (ev_queue->is_closed) { +			spin_unlock_irq(&ev_queue->lock); +			return -EIO; +		} +		spin_unlock_irq(&ev_queue->lock);  		if (filp->f_flags & O_NONBLOCK)  			return -EAGAIN; @@ -233,12 +237,6 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,  			return -ERESTARTSYS;  		spin_lock_irq(&ev_queue->lock); - -		/* If device was disassociated and no event exists set an error */ -		if (list_empty(&ev_queue->event_list) && ev_queue->is_closed) { -			spin_unlock_irq(&ev_queue->lock); -			return -EIO; -		}  	}  	event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list); @@ -1264,7 +1262,7 @@ static int __init ib_uverbs_init(void)  		goto out_alloc;  	} -	uverbs_class = class_create(THIS_MODULE, "infiniband_verbs"); +	uverbs_class = class_create("infiniband_verbs");  	if (IS_ERR(uverbs_class)) {  		ret = PTR_ERR(uverbs_class);  		pr_err("user_verbs: couldn't create class infiniband_verbs\n"); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 11b1c1603aeb..b99b3cc283b6 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -532,6 +532,8 @@ static struct ib_ah *_rdma_create_ah(struct ib_pd *pd,  	else  		ret = device->ops.create_ah(ah, &init_attr, NULL);  	if (ret) { +		if (ah->sgid_attr) +			rdma_put_gid_attr(ah->sgid_attr);  		kfree(ah);  		return ERR_PTR(ret);  	}  |