xref: /OK3568_Linux_fs/kernel/drivers/infiniband/core/uverbs.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
3*4882a593Smuzhiyun  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
4*4882a593Smuzhiyun  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5*4882a593Smuzhiyun  * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
6*4882a593Smuzhiyun  * Copyright (c) 2005 PathScale, Inc. All rights reserved.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * This software is available to you under a choice of one of two
9*4882a593Smuzhiyun  * licenses.  You may choose to be licensed under the terms of the GNU
10*4882a593Smuzhiyun  * General Public License (GPL) Version 2, available from the file
11*4882a593Smuzhiyun  * COPYING in the main directory of this source tree, or the
12*4882a593Smuzhiyun  * OpenIB.org BSD license below:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *     Redistribution and use in source and binary forms, with or
15*4882a593Smuzhiyun  *     without modification, are permitted provided that the following
16*4882a593Smuzhiyun  *     conditions are met:
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  *      - Redistributions of source code must retain the above
19*4882a593Smuzhiyun  *        copyright notice, this list of conditions and the following
20*4882a593Smuzhiyun  *        disclaimer.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  *      - Redistributions in binary form must reproduce the above
23*4882a593Smuzhiyun  *        copyright notice, this list of conditions and the following
24*4882a593Smuzhiyun  *        disclaimer in the documentation and/or other materials
25*4882a593Smuzhiyun  *        provided with the distribution.
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28*4882a593Smuzhiyun  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29*4882a593Smuzhiyun  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30*4882a593Smuzhiyun  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31*4882a593Smuzhiyun  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32*4882a593Smuzhiyun  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33*4882a593Smuzhiyun  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34*4882a593Smuzhiyun  * SOFTWARE.
35*4882a593Smuzhiyun  */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #ifndef UVERBS_H
38*4882a593Smuzhiyun #define UVERBS_H
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #include <linux/kref.h>
41*4882a593Smuzhiyun #include <linux/idr.h>
42*4882a593Smuzhiyun #include <linux/mutex.h>
43*4882a593Smuzhiyun #include <linux/completion.h>
44*4882a593Smuzhiyun #include <linux/cdev.h>
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #include <rdma/ib_verbs.h>
47*4882a593Smuzhiyun #include <rdma/ib_umem.h>
48*4882a593Smuzhiyun #include <rdma/ib_user_verbs.h>
49*4882a593Smuzhiyun #include <rdma/uverbs_std_types.h>
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define UVERBS_MODULE_NAME ib_uverbs
52*4882a593Smuzhiyun #include <rdma/uverbs_named_ioctl.h>
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun static inline void
ib_uverbs_init_udata(struct ib_udata * udata,const void __user * ibuf,void __user * obuf,size_t ilen,size_t olen)55*4882a593Smuzhiyun ib_uverbs_init_udata(struct ib_udata *udata,
56*4882a593Smuzhiyun 		     const void __user *ibuf,
57*4882a593Smuzhiyun 		     void __user *obuf,
58*4882a593Smuzhiyun 		     size_t ilen, size_t olen)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	udata->inbuf  = ibuf;
61*4882a593Smuzhiyun 	udata->outbuf = obuf;
62*4882a593Smuzhiyun 	udata->inlen  = ilen;
63*4882a593Smuzhiyun 	udata->outlen = olen;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun static inline void
ib_uverbs_init_udata_buf_or_null(struct ib_udata * udata,const void __user * ibuf,void __user * obuf,size_t ilen,size_t olen)67*4882a593Smuzhiyun ib_uverbs_init_udata_buf_or_null(struct ib_udata *udata,
68*4882a593Smuzhiyun 				 const void __user *ibuf,
69*4882a593Smuzhiyun 				 void __user *obuf,
70*4882a593Smuzhiyun 				 size_t ilen, size_t olen)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	ib_uverbs_init_udata(udata,
73*4882a593Smuzhiyun 			     ilen ? ibuf : NULL, olen ? obuf : NULL,
74*4882a593Smuzhiyun 			     ilen, olen);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun  * Our lifetime rules for these structs are the following:
79*4882a593Smuzhiyun  *
80*4882a593Smuzhiyun  * struct ib_uverbs_device: One reference is held by the module and
81*4882a593Smuzhiyun  * released in ib_uverbs_remove_one().  Another reference is taken by
82*4882a593Smuzhiyun  * ib_uverbs_open() each time the character special file is opened,
83*4882a593Smuzhiyun  * and released in ib_uverbs_release_file() when the file is released.
84*4882a593Smuzhiyun  *
85*4882a593Smuzhiyun  * struct ib_uverbs_file: One reference is held by the VFS and
86*4882a593Smuzhiyun  * released when the file is closed.  Another reference is taken when
87*4882a593Smuzhiyun  * an asynchronous event queue file is created and released when the
88*4882a593Smuzhiyun  * event file is closed.
89*4882a593Smuzhiyun  *
90*4882a593Smuzhiyun  * struct ib_uverbs_event_queue: Base structure for
91*4882a593Smuzhiyun  * struct ib_uverbs_async_event_file and struct ib_uverbs_completion_event_file.
92*4882a593Smuzhiyun  * One reference is held by the VFS and released when the file is closed.
93*4882a593Smuzhiyun  * For asynchronous event files, another reference is held by the corresponding
94*4882a593Smuzhiyun  * main context file and released when that file is closed.  For completion
95*4882a593Smuzhiyun  * event files, a reference is taken when a CQ is created that uses the file,
96*4882a593Smuzhiyun  * and released when the CQ is destroyed.
97*4882a593Smuzhiyun  */
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun struct ib_uverbs_device {
100*4882a593Smuzhiyun 	atomic_t				refcount;
101*4882a593Smuzhiyun 	u32					num_comp_vectors;
102*4882a593Smuzhiyun 	struct completion			comp;
103*4882a593Smuzhiyun 	struct device				dev;
104*4882a593Smuzhiyun 	/* First group for device attributes, NULL terminated array */
105*4882a593Smuzhiyun 	const struct attribute_group		*groups[2];
106*4882a593Smuzhiyun 	struct ib_device	__rcu	       *ib_dev;
107*4882a593Smuzhiyun 	int					devnum;
108*4882a593Smuzhiyun 	struct cdev			        cdev;
109*4882a593Smuzhiyun 	struct rb_root				xrcd_tree;
110*4882a593Smuzhiyun 	struct mutex				xrcd_tree_mutex;
111*4882a593Smuzhiyun 	struct srcu_struct			disassociate_srcu;
112*4882a593Smuzhiyun 	struct mutex				lists_mutex; /* protect lists */
113*4882a593Smuzhiyun 	struct list_head			uverbs_file_list;
114*4882a593Smuzhiyun 	struct uverbs_api			*uapi;
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun struct ib_uverbs_event_queue {
118*4882a593Smuzhiyun 	spinlock_t				lock;
119*4882a593Smuzhiyun 	int					is_closed;
120*4882a593Smuzhiyun 	wait_queue_head_t			poll_wait;
121*4882a593Smuzhiyun 	struct fasync_struct		       *async_queue;
122*4882a593Smuzhiyun 	struct list_head			event_list;
123*4882a593Smuzhiyun };
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun struct ib_uverbs_async_event_file {
126*4882a593Smuzhiyun 	struct ib_uobject			uobj;
127*4882a593Smuzhiyun 	struct ib_uverbs_event_queue		ev_queue;
128*4882a593Smuzhiyun 	struct ib_event_handler			event_handler;
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun struct ib_uverbs_completion_event_file {
132*4882a593Smuzhiyun 	struct ib_uobject			uobj;
133*4882a593Smuzhiyun 	struct ib_uverbs_event_queue		ev_queue;
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun struct ib_uverbs_file {
137*4882a593Smuzhiyun 	struct kref				ref;
138*4882a593Smuzhiyun 	struct ib_uverbs_device		       *device;
139*4882a593Smuzhiyun 	struct mutex				ucontext_lock;
140*4882a593Smuzhiyun 	/*
141*4882a593Smuzhiyun 	 * ucontext must be accessed via ib_uverbs_get_ucontext() or with
142*4882a593Smuzhiyun 	 * ucontext_lock held
143*4882a593Smuzhiyun 	 */
144*4882a593Smuzhiyun 	struct ib_ucontext		       *ucontext;
145*4882a593Smuzhiyun 	struct ib_uverbs_async_event_file      *default_async_file;
146*4882a593Smuzhiyun 	struct list_head			list;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	/*
149*4882a593Smuzhiyun 	 * To access the uobjects list hw_destroy_rwsem must be held for write
150*4882a593Smuzhiyun 	 * OR hw_destroy_rwsem held for read AND uobjects_lock held.
151*4882a593Smuzhiyun 	 * hw_destroy_rwsem should be called across any destruction of the HW
152*4882a593Smuzhiyun 	 * object of an associated uobject.
153*4882a593Smuzhiyun 	 */
154*4882a593Smuzhiyun 	struct rw_semaphore	hw_destroy_rwsem;
155*4882a593Smuzhiyun 	spinlock_t		uobjects_lock;
156*4882a593Smuzhiyun 	struct list_head	uobjects;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	struct mutex umap_lock;
159*4882a593Smuzhiyun 	struct list_head umaps;
160*4882a593Smuzhiyun 	struct page *disassociate_page;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	struct xarray		idr;
163*4882a593Smuzhiyun };
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun struct ib_uverbs_event {
166*4882a593Smuzhiyun 	union {
167*4882a593Smuzhiyun 		struct ib_uverbs_async_event_desc	async;
168*4882a593Smuzhiyun 		struct ib_uverbs_comp_event_desc	comp;
169*4882a593Smuzhiyun 	}					desc;
170*4882a593Smuzhiyun 	struct list_head			list;
171*4882a593Smuzhiyun 	struct list_head			obj_list;
172*4882a593Smuzhiyun 	u32				       *counter;
173*4882a593Smuzhiyun };
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun struct ib_uverbs_mcast_entry {
176*4882a593Smuzhiyun 	struct list_head	list;
177*4882a593Smuzhiyun 	union ib_gid 		gid;
178*4882a593Smuzhiyun 	u16 			lid;
179*4882a593Smuzhiyun };
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun struct ib_uevent_object {
182*4882a593Smuzhiyun 	struct ib_uobject	uobject;
183*4882a593Smuzhiyun 	struct ib_uverbs_async_event_file *event_file;
184*4882a593Smuzhiyun 	/* List member for ib_uverbs_async_event_file list */
185*4882a593Smuzhiyun 	struct list_head	event_list;
186*4882a593Smuzhiyun 	u32			events_reported;
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun struct ib_uxrcd_object {
190*4882a593Smuzhiyun 	struct ib_uobject	uobject;
191*4882a593Smuzhiyun 	atomic_t		refcnt;
192*4882a593Smuzhiyun };
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun struct ib_usrq_object {
195*4882a593Smuzhiyun 	struct ib_uevent_object	uevent;
196*4882a593Smuzhiyun 	struct ib_uxrcd_object *uxrcd;
197*4882a593Smuzhiyun };
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun struct ib_uqp_object {
200*4882a593Smuzhiyun 	struct ib_uevent_object	uevent;
201*4882a593Smuzhiyun 	/* lock for mcast list */
202*4882a593Smuzhiyun 	struct mutex		mcast_lock;
203*4882a593Smuzhiyun 	struct list_head 	mcast_list;
204*4882a593Smuzhiyun 	struct ib_uxrcd_object *uxrcd;
205*4882a593Smuzhiyun };
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun struct ib_uwq_object {
208*4882a593Smuzhiyun 	struct ib_uevent_object	uevent;
209*4882a593Smuzhiyun };
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun struct ib_ucq_object {
212*4882a593Smuzhiyun 	struct ib_uevent_object uevent;
213*4882a593Smuzhiyun 	struct list_head	comp_list;
214*4882a593Smuzhiyun 	u32			comp_events_reported;
215*4882a593Smuzhiyun };
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun extern const struct file_operations uverbs_event_fops;
218*4882a593Smuzhiyun extern const struct file_operations uverbs_async_event_fops;
219*4882a593Smuzhiyun void ib_uverbs_init_event_queue(struct ib_uverbs_event_queue *ev_queue);
220*4882a593Smuzhiyun void ib_uverbs_init_async_event_file(struct ib_uverbs_async_event_file *ev_file);
221*4882a593Smuzhiyun void ib_uverbs_free_event_queue(struct ib_uverbs_event_queue *event_queue);
222*4882a593Smuzhiyun void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
223*4882a593Smuzhiyun int uverbs_async_event_release(struct inode *inode, struct file *filp);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun int ib_alloc_ucontext(struct uverbs_attr_bundle *attrs);
226*4882a593Smuzhiyun int ib_init_ucontext(struct uverbs_attr_bundle *attrs);
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun void ib_uverbs_release_ucq(struct ib_uverbs_completion_event_file *ev_file,
229*4882a593Smuzhiyun 			   struct ib_ucq_object *uobj);
230*4882a593Smuzhiyun void ib_uverbs_release_uevent(struct ib_uevent_object *uobj);
231*4882a593Smuzhiyun void ib_uverbs_release_file(struct kref *ref);
232*4882a593Smuzhiyun void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file,
233*4882a593Smuzhiyun 			     __u64 element, __u64 event,
234*4882a593Smuzhiyun 			     struct list_head *obj_list, u32 *counter);
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
237*4882a593Smuzhiyun void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
238*4882a593Smuzhiyun void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
239*4882a593Smuzhiyun void ib_uverbs_wq_event_handler(struct ib_event *event, void *context_ptr);
240*4882a593Smuzhiyun void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);
241*4882a593Smuzhiyun int ib_uverbs_dealloc_xrcd(struct ib_uobject *uobject, struct ib_xrcd *xrcd,
242*4882a593Smuzhiyun 			   enum rdma_remove_reason why,
243*4882a593Smuzhiyun 			   struct uverbs_attr_bundle *attrs);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun int uverbs_dealloc_mw(struct ib_mw *mw);
246*4882a593Smuzhiyun void ib_uverbs_detach_umcast(struct ib_qp *qp,
247*4882a593Smuzhiyun 			     struct ib_uqp_object *uobj);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun struct ib_uverbs_flow_spec {
252*4882a593Smuzhiyun 	union {
253*4882a593Smuzhiyun 		union {
254*4882a593Smuzhiyun 			struct ib_uverbs_flow_spec_hdr hdr;
255*4882a593Smuzhiyun 			struct {
256*4882a593Smuzhiyun 				__u32 type;
257*4882a593Smuzhiyun 				__u16 size;
258*4882a593Smuzhiyun 				__u16 reserved;
259*4882a593Smuzhiyun 			};
260*4882a593Smuzhiyun 		};
261*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_eth     eth;
262*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_ipv4    ipv4;
263*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_esp     esp;
264*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_tcp_udp tcp_udp;
265*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_ipv6    ipv6;
266*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_action_tag	flow_tag;
267*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_action_drop	drop;
268*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_action_handle action;
269*4882a593Smuzhiyun 		struct ib_uverbs_flow_spec_action_count flow_count;
270*4882a593Smuzhiyun 	};
271*4882a593Smuzhiyun };
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
274*4882a593Smuzhiyun 					  const void *kern_spec_mask,
275*4882a593Smuzhiyun 					  const void *kern_spec_val,
276*4882a593Smuzhiyun 					  size_t kern_filter_sz,
277*4882a593Smuzhiyun 					  union ib_flow_spec *ib_spec);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun /*
280*4882a593Smuzhiyun  * ib_uverbs_query_port_resp.port_cap_flags started out as just a copy of the
281*4882a593Smuzhiyun  * PortInfo CapabilityMask, but was extended with unique bits.
282*4882a593Smuzhiyun  */
make_port_cap_flags(const struct ib_port_attr * attr)283*4882a593Smuzhiyun static inline u32 make_port_cap_flags(const struct ib_port_attr *attr)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	u32 res;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	/* All IBA CapabilityMask bits are passed through here, except bit 26,
288*4882a593Smuzhiyun 	 * which is overridden with IP_BASED_GIDS. This is due to a historical
289*4882a593Smuzhiyun 	 * mistake in the implementation of IP_BASED_GIDS. Otherwise all other
290*4882a593Smuzhiyun 	 * bits match the IBA definition across all kernel versions.
291*4882a593Smuzhiyun 	 */
292*4882a593Smuzhiyun 	res = attr->port_cap_flags & ~(u32)IB_UVERBS_PCF_IP_BASED_GIDS;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	if (attr->ip_gids)
295*4882a593Smuzhiyun 		res |= IB_UVERBS_PCF_IP_BASED_GIDS;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	return res;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun static inline struct ib_uverbs_async_event_file *
ib_uverbs_get_async_event(struct uverbs_attr_bundle * attrs,u16 id)301*4882a593Smuzhiyun ib_uverbs_get_async_event(struct uverbs_attr_bundle *attrs,
302*4882a593Smuzhiyun 			  u16 id)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	struct ib_uobject *async_ev_file_uobj;
305*4882a593Smuzhiyun 	struct ib_uverbs_async_event_file *async_ev_file;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	async_ev_file_uobj = uverbs_attr_get_uobject(attrs, id);
308*4882a593Smuzhiyun 	if (IS_ERR(async_ev_file_uobj))
309*4882a593Smuzhiyun 		async_ev_file = READ_ONCE(attrs->ufile->default_async_file);
310*4882a593Smuzhiyun 	else
311*4882a593Smuzhiyun 		async_ev_file = container_of(async_ev_file_uobj,
312*4882a593Smuzhiyun 				       struct ib_uverbs_async_event_file,
313*4882a593Smuzhiyun 				       uobj);
314*4882a593Smuzhiyun 	if (async_ev_file)
315*4882a593Smuzhiyun 		uverbs_uobject_get(&async_ev_file->uobj);
316*4882a593Smuzhiyun 	return async_ev_file;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun void copy_port_attr_to_resp(struct ib_port_attr *attr,
320*4882a593Smuzhiyun 			    struct ib_uverbs_query_port_resp *resp,
321*4882a593Smuzhiyun 			    struct ib_device *ib_dev, u8 port_num);
322*4882a593Smuzhiyun #endif /* UVERBS_H */
323