xref: /linux/drivers/infiniband/core/uverbs_cmd.c (revision 54a8a2220c936a47840c9a3d74910c5a56fae2ed)
1 /*
2  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005 Cisco Systems.  All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  *
33  * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
34  */
35 
36 #include <asm/uaccess.h>
37 
38 #include "uverbs.h"
39 
40 #define INIT_UDATA(udata, ibuf, obuf, ilen, olen)			\
41 	do {								\
42 		(udata)->inbuf  = (void __user *) (ibuf);		\
43 		(udata)->outbuf = (void __user *) (obuf);		\
44 		(udata)->inlen  = (ilen);				\
45 		(udata)->outlen = (olen);				\
46 	} while (0)
47 
48 ssize_t ib_uverbs_query_params(struct ib_uverbs_file *file,
49 			       const char __user *buf,
50 			       int in_len, int out_len)
51 {
52 	struct ib_uverbs_query_params      cmd;
53 	struct ib_uverbs_query_params_resp resp;
54 
55 	if (out_len < sizeof resp)
56 		return -ENOSPC;
57 
58 	if (copy_from_user(&cmd, buf, sizeof cmd))
59 		return -EFAULT;
60 
61 	memset(&resp, 0, sizeof resp);
62 
63 	resp.num_cq_events = file->device->num_comp;
64 
65 	if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp))
66 	    return -EFAULT;
67 
68 	return in_len;
69 }
70 
71 ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
72 			      const char __user *buf,
73 			      int in_len, int out_len)
74 {
75 	struct ib_uverbs_get_context      cmd;
76 	struct ib_uverbs_get_context_resp resp;
77 	struct ib_udata                   udata;
78 	struct ib_device                 *ibdev = file->device->ib_dev;
79 	struct ib_ucontext		 *ucontext;
80 	int i;
81 	int ret;
82 
83 	if (out_len < sizeof resp)
84 		return -ENOSPC;
85 
86 	if (copy_from_user(&cmd, buf, sizeof cmd))
87 		return -EFAULT;
88 
89 	down(&file->mutex);
90 
91 	if (file->ucontext) {
92 		ret = -EINVAL;
93 		goto err;
94 	}
95 
96 	INIT_UDATA(&udata, buf + sizeof cmd,
97 		   (unsigned long) cmd.response + sizeof resp,
98 		   in_len - sizeof cmd, out_len - sizeof resp);
99 
100 	ucontext = ibdev->alloc_ucontext(ibdev, &udata);
101 	if (IS_ERR(ucontext))
102 		return PTR_ERR(file->ucontext);
103 
104 	ucontext->device = ibdev;
105 	INIT_LIST_HEAD(&ucontext->pd_list);
106 	INIT_LIST_HEAD(&ucontext->mr_list);
107 	INIT_LIST_HEAD(&ucontext->mw_list);
108 	INIT_LIST_HEAD(&ucontext->cq_list);
109 	INIT_LIST_HEAD(&ucontext->qp_list);
110 	INIT_LIST_HEAD(&ucontext->srq_list);
111 	INIT_LIST_HEAD(&ucontext->ah_list);
112 
113 	resp.async_fd = file->async_file.fd;
114 	for (i = 0; i < file->device->num_comp; ++i)
115 		if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
116 				 i * sizeof (__u32),
117 				 &file->comp_file[i].fd, sizeof (__u32))) {
118 			ret = -EFAULT;
119 			goto err_free;
120 		}
121 
122 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
123 			 &resp, sizeof resp)) {
124 		ret = -EFAULT;
125 		goto err_free;
126 	}
127 
128 	file->ucontext = ucontext;
129 	up(&file->mutex);
130 
131 	return in_len;
132 
133 err_free:
134 	ibdev->dealloc_ucontext(ucontext);
135 
136 err:
137 	up(&file->mutex);
138 	return ret;
139 }
140 
141 ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
142 			       const char __user *buf,
143 			       int in_len, int out_len)
144 {
145 	struct ib_uverbs_query_device      cmd;
146 	struct ib_uverbs_query_device_resp resp;
147 	struct ib_device_attr              attr;
148 	int                                ret;
149 
150 	if (out_len < sizeof resp)
151 		return -ENOSPC;
152 
153 	if (copy_from_user(&cmd, buf, sizeof cmd))
154 		return -EFAULT;
155 
156 	ret = ib_query_device(file->device->ib_dev, &attr);
157 	if (ret)
158 		return ret;
159 
160 	memset(&resp, 0, sizeof resp);
161 
162 	resp.fw_ver 		       = attr.fw_ver;
163 	resp.node_guid 		       = attr.node_guid;
164 	resp.sys_image_guid 	       = attr.sys_image_guid;
165 	resp.max_mr_size 	       = attr.max_mr_size;
166 	resp.page_size_cap 	       = attr.page_size_cap;
167 	resp.vendor_id 		       = attr.vendor_id;
168 	resp.vendor_part_id 	       = attr.vendor_part_id;
169 	resp.hw_ver 		       = attr.hw_ver;
170 	resp.max_qp 		       = attr.max_qp;
171 	resp.max_qp_wr 		       = attr.max_qp_wr;
172 	resp.device_cap_flags 	       = attr.device_cap_flags;
173 	resp.max_sge 		       = attr.max_sge;
174 	resp.max_sge_rd 	       = attr.max_sge_rd;
175 	resp.max_cq 		       = attr.max_cq;
176 	resp.max_cqe 		       = attr.max_cqe;
177 	resp.max_mr 		       = attr.max_mr;
178 	resp.max_pd 		       = attr.max_pd;
179 	resp.max_qp_rd_atom 	       = attr.max_qp_rd_atom;
180 	resp.max_ee_rd_atom 	       = attr.max_ee_rd_atom;
181 	resp.max_res_rd_atom 	       = attr.max_res_rd_atom;
182 	resp.max_qp_init_rd_atom       = attr.max_qp_init_rd_atom;
183 	resp.max_ee_init_rd_atom       = attr.max_ee_init_rd_atom;
184 	resp.atomic_cap 	       = attr.atomic_cap;
185 	resp.max_ee 		       = attr.max_ee;
186 	resp.max_rdd 		       = attr.max_rdd;
187 	resp.max_mw 		       = attr.max_mw;
188 	resp.max_raw_ipv6_qp 	       = attr.max_raw_ipv6_qp;
189 	resp.max_raw_ethy_qp 	       = attr.max_raw_ethy_qp;
190 	resp.max_mcast_grp 	       = attr.max_mcast_grp;
191 	resp.max_mcast_qp_attach       = attr.max_mcast_qp_attach;
192 	resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach;
193 	resp.max_ah 		       = attr.max_ah;
194 	resp.max_fmr 		       = attr.max_fmr;
195 	resp.max_map_per_fmr 	       = attr.max_map_per_fmr;
196 	resp.max_srq 		       = attr.max_srq;
197 	resp.max_srq_wr 	       = attr.max_srq_wr;
198 	resp.max_srq_sge 	       = attr.max_srq_sge;
199 	resp.max_pkeys 		       = attr.max_pkeys;
200 	resp.local_ca_ack_delay        = attr.local_ca_ack_delay;
201 	resp.phys_port_cnt	       = file->device->ib_dev->phys_port_cnt;
202 
203 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
204 			 &resp, sizeof resp))
205 		return -EFAULT;
206 
207 	return in_len;
208 }
209 
210 ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
211 			     const char __user *buf,
212 			     int in_len, int out_len)
213 {
214 	struct ib_uverbs_query_port      cmd;
215 	struct ib_uverbs_query_port_resp resp;
216 	struct ib_port_attr              attr;
217 	int                              ret;
218 
219 	if (out_len < sizeof resp)
220 		return -ENOSPC;
221 
222 	if (copy_from_user(&cmd, buf, sizeof cmd))
223 		return -EFAULT;
224 
225 	ret = ib_query_port(file->device->ib_dev, cmd.port_num, &attr);
226 	if (ret)
227 		return ret;
228 
229 	memset(&resp, 0, sizeof resp);
230 
231 	resp.state 	     = attr.state;
232 	resp.max_mtu 	     = attr.max_mtu;
233 	resp.active_mtu      = attr.active_mtu;
234 	resp.gid_tbl_len     = attr.gid_tbl_len;
235 	resp.port_cap_flags  = attr.port_cap_flags;
236 	resp.max_msg_sz      = attr.max_msg_sz;
237 	resp.bad_pkey_cntr   = attr.bad_pkey_cntr;
238 	resp.qkey_viol_cntr  = attr.qkey_viol_cntr;
239 	resp.pkey_tbl_len    = attr.pkey_tbl_len;
240 	resp.lid 	     = attr.lid;
241 	resp.sm_lid 	     = attr.sm_lid;
242 	resp.lmc 	     = attr.lmc;
243 	resp.max_vl_num      = attr.max_vl_num;
244 	resp.sm_sl 	     = attr.sm_sl;
245 	resp.subnet_timeout  = attr.subnet_timeout;
246 	resp.init_type_reply = attr.init_type_reply;
247 	resp.active_width    = attr.active_width;
248 	resp.active_speed    = attr.active_speed;
249 	resp.phys_state      = attr.phys_state;
250 
251 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
252 			 &resp, sizeof resp))
253 		return -EFAULT;
254 
255 	return in_len;
256 }
257 
258 ssize_t ib_uverbs_query_gid(struct ib_uverbs_file *file,
259 			    const char __user *buf,
260 			    int in_len, int out_len)
261 {
262 	struct ib_uverbs_query_gid      cmd;
263 	struct ib_uverbs_query_gid_resp resp;
264 	int                             ret;
265 
266 	if (out_len < sizeof resp)
267 		return -ENOSPC;
268 
269 	if (copy_from_user(&cmd, buf, sizeof cmd))
270 		return -EFAULT;
271 
272 	memset(&resp, 0, sizeof resp);
273 
274 	ret = ib_query_gid(file->device->ib_dev, cmd.port_num, cmd.index,
275 			   (union ib_gid *) resp.gid);
276 	if (ret)
277 		return ret;
278 
279 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
280 			 &resp, sizeof resp))
281 		return -EFAULT;
282 
283 	return in_len;
284 }
285 
286 ssize_t ib_uverbs_query_pkey(struct ib_uverbs_file *file,
287 			     const char __user *buf,
288 			     int in_len, int out_len)
289 {
290 	struct ib_uverbs_query_pkey      cmd;
291 	struct ib_uverbs_query_pkey_resp resp;
292 	int                              ret;
293 
294 	if (out_len < sizeof resp)
295 		return -ENOSPC;
296 
297 	if (copy_from_user(&cmd, buf, sizeof cmd))
298 		return -EFAULT;
299 
300 	memset(&resp, 0, sizeof resp);
301 
302 	ret = ib_query_pkey(file->device->ib_dev, cmd.port_num, cmd.index,
303 			    &resp.pkey);
304 	if (ret)
305 		return ret;
306 
307 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
308 			 &resp, sizeof resp))
309 		return -EFAULT;
310 
311 	return in_len;
312 }
313 
314 ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
315 			   const char __user *buf,
316 			   int in_len, int out_len)
317 {
318 	struct ib_uverbs_alloc_pd      cmd;
319 	struct ib_uverbs_alloc_pd_resp resp;
320 	struct ib_udata                udata;
321 	struct ib_uobject             *uobj;
322 	struct ib_pd                  *pd;
323 	int                            ret;
324 
325 	if (out_len < sizeof resp)
326 		return -ENOSPC;
327 
328 	if (copy_from_user(&cmd, buf, sizeof cmd))
329 		return -EFAULT;
330 
331 	INIT_UDATA(&udata, buf + sizeof cmd,
332 		   (unsigned long) cmd.response + sizeof resp,
333 		   in_len - sizeof cmd, out_len - sizeof resp);
334 
335 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
336 	if (!uobj)
337 		return -ENOMEM;
338 
339 	uobj->context = file->ucontext;
340 
341 	pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
342 					    file->ucontext, &udata);
343 	if (IS_ERR(pd)) {
344 		ret = PTR_ERR(pd);
345 		goto err;
346 	}
347 
348 	pd->device  = file->device->ib_dev;
349 	pd->uobject = uobj;
350 	atomic_set(&pd->usecnt, 0);
351 
352 retry:
353 	if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
354 		ret = -ENOMEM;
355 		goto err_pd;
356 	}
357 
358 	down(&ib_uverbs_idr_mutex);
359 	ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id);
360 	up(&ib_uverbs_idr_mutex);
361 
362 	if (ret == -EAGAIN)
363 		goto retry;
364 	if (ret)
365 		goto err_pd;
366 
367 	down(&file->mutex);
368 	list_add_tail(&uobj->list, &file->ucontext->pd_list);
369 	up(&file->mutex);
370 
371 	memset(&resp, 0, sizeof resp);
372 	resp.pd_handle = uobj->id;
373 
374 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
375 			 &resp, sizeof resp)) {
376 		ret = -EFAULT;
377 		goto err_list;
378 	}
379 
380 	return in_len;
381 
382 err_list:
383  	down(&file->mutex);
384 	list_del(&uobj->list);
385 	up(&file->mutex);
386 
387 	down(&ib_uverbs_idr_mutex);
388 	idr_remove(&ib_uverbs_pd_idr, uobj->id);
389 	up(&ib_uverbs_idr_mutex);
390 
391 err_pd:
392 	ib_dealloc_pd(pd);
393 
394 err:
395 	kfree(uobj);
396 	return ret;
397 }
398 
399 ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
400 			     const char __user *buf,
401 			     int in_len, int out_len)
402 {
403 	struct ib_uverbs_dealloc_pd cmd;
404 	struct ib_pd               *pd;
405 	struct ib_uobject          *uobj;
406 	int                         ret = -EINVAL;
407 
408 	if (copy_from_user(&cmd, buf, sizeof cmd))
409 		return -EFAULT;
410 
411 	down(&ib_uverbs_idr_mutex);
412 
413 	pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
414 	if (!pd || pd->uobject->context != file->ucontext)
415 		goto out;
416 
417 	uobj = pd->uobject;
418 
419 	ret = ib_dealloc_pd(pd);
420 	if (ret)
421 		goto out;
422 
423 	idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
424 
425 	down(&file->mutex);
426 	list_del(&uobj->list);
427 	up(&file->mutex);
428 
429 	kfree(uobj);
430 
431 out:
432 	up(&ib_uverbs_idr_mutex);
433 
434 	return ret ? ret : in_len;
435 }
436 
437 ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
438 			 const char __user *buf, int in_len,
439 			 int out_len)
440 {
441 	struct ib_uverbs_reg_mr      cmd;
442 	struct ib_uverbs_reg_mr_resp resp;
443 	struct ib_udata              udata;
444 	struct ib_umem_object       *obj;
445 	struct ib_pd                *pd;
446 	struct ib_mr                *mr;
447 	int                          ret;
448 
449 	if (out_len < sizeof resp)
450 		return -ENOSPC;
451 
452 	if (copy_from_user(&cmd, buf, sizeof cmd))
453 		return -EFAULT;
454 
455 	INIT_UDATA(&udata, buf + sizeof cmd,
456 		   (unsigned long) cmd.response + sizeof resp,
457 		   in_len - sizeof cmd, out_len - sizeof resp);
458 
459 	if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
460 		return -EINVAL;
461 
462 	obj = kmalloc(sizeof *obj, GFP_KERNEL);
463 	if (!obj)
464 		return -ENOMEM;
465 
466 	obj->uobject.context = file->ucontext;
467 
468 	/*
469 	 * We ask for writable memory if any access flags other than
470 	 * "remote read" are set.  "Local write" and "remote write"
471 	 * obviously require write access.  "Remote atomic" can do
472 	 * things like fetch and add, which will modify memory, and
473 	 * "MW bind" can change permissions by binding a window.
474 	 */
475 	ret = ib_umem_get(file->device->ib_dev, &obj->umem,
476 			  (void *) (unsigned long) cmd.start, cmd.length,
477 			  !!(cmd.access_flags & ~IB_ACCESS_REMOTE_READ));
478 	if (ret)
479 		goto err_free;
480 
481 	obj->umem.virt_base = cmd.hca_va;
482 
483 	down(&ib_uverbs_idr_mutex);
484 
485 	pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
486 	if (!pd || pd->uobject->context != file->ucontext) {
487 		ret = -EINVAL;
488 		goto err_up;
489 	}
490 
491 	if (!pd->device->reg_user_mr) {
492 		ret = -ENOSYS;
493 		goto err_up;
494 	}
495 
496 	mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata);
497 	if (IS_ERR(mr)) {
498 		ret = PTR_ERR(mr);
499 		goto err_up;
500 	}
501 
502 	mr->device  = pd->device;
503 	mr->pd      = pd;
504 	mr->uobject = &obj->uobject;
505 	atomic_inc(&pd->usecnt);
506 	atomic_set(&mr->usecnt, 0);
507 
508 	memset(&resp, 0, sizeof resp);
509 	resp.lkey = mr->lkey;
510 	resp.rkey = mr->rkey;
511 
512 retry:
513 	if (!idr_pre_get(&ib_uverbs_mr_idr, GFP_KERNEL)) {
514 		ret = -ENOMEM;
515 		goto err_unreg;
516 	}
517 
518 	ret = idr_get_new(&ib_uverbs_mr_idr, mr, &obj->uobject.id);
519 
520 	if (ret == -EAGAIN)
521 		goto retry;
522 	if (ret)
523 		goto err_unreg;
524 
525 	resp.mr_handle = obj->uobject.id;
526 
527 	down(&file->mutex);
528 	list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
529 	up(&file->mutex);
530 
531 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
532 			 &resp, sizeof resp)) {
533 		ret = -EFAULT;
534 		goto err_list;
535 	}
536 
537 	up(&ib_uverbs_idr_mutex);
538 
539 	return in_len;
540 
541 err_list:
542 	down(&file->mutex);
543 	list_del(&obj->uobject.list);
544 	up(&file->mutex);
545 
546 err_unreg:
547 	ib_dereg_mr(mr);
548 
549 err_up:
550 	up(&ib_uverbs_idr_mutex);
551 
552 	ib_umem_release(file->device->ib_dev, &obj->umem);
553 
554 err_free:
555 	kfree(obj);
556 	return ret;
557 }
558 
559 ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
560 			   const char __user *buf, int in_len,
561 			   int out_len)
562 {
563 	struct ib_uverbs_dereg_mr cmd;
564 	struct ib_mr             *mr;
565 	struct ib_umem_object    *memobj;
566 	int                       ret = -EINVAL;
567 
568 	if (copy_from_user(&cmd, buf, sizeof cmd))
569 		return -EFAULT;
570 
571 	down(&ib_uverbs_idr_mutex);
572 
573 	mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle);
574 	if (!mr || mr->uobject->context != file->ucontext)
575 		goto out;
576 
577 	memobj = container_of(mr->uobject, struct ib_umem_object, uobject);
578 
579 	ret = ib_dereg_mr(mr);
580 	if (ret)
581 		goto out;
582 
583 	idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
584 
585 	down(&file->mutex);
586 	list_del(&memobj->uobject.list);
587 	up(&file->mutex);
588 
589 	ib_umem_release(file->device->ib_dev, &memobj->umem);
590 	kfree(memobj);
591 
592 out:
593 	up(&ib_uverbs_idr_mutex);
594 
595 	return ret ? ret : in_len;
596 }
597 
598 ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
599 			    const char __user *buf, int in_len,
600 			    int out_len)
601 {
602 	struct ib_uverbs_create_cq      cmd;
603 	struct ib_uverbs_create_cq_resp resp;
604 	struct ib_udata                 udata;
605 	struct ib_ucq_object           *uobj;
606 	struct ib_cq                   *cq;
607 	int                             ret;
608 
609 	if (out_len < sizeof resp)
610 		return -ENOSPC;
611 
612 	if (copy_from_user(&cmd, buf, sizeof cmd))
613 		return -EFAULT;
614 
615 	INIT_UDATA(&udata, buf + sizeof cmd,
616 		   (unsigned long) cmd.response + sizeof resp,
617 		   in_len - sizeof cmd, out_len - sizeof resp);
618 
619 	if (cmd.event_handler >= file->device->num_comp)
620 		return -EINVAL;
621 
622 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
623 	if (!uobj)
624 		return -ENOMEM;
625 
626 	uobj->uobject.user_handle   = cmd.user_handle;
627 	uobj->uobject.context       = file->ucontext;
628 	uobj->comp_events_reported  = 0;
629 	uobj->async_events_reported = 0;
630 	INIT_LIST_HEAD(&uobj->comp_list);
631 	INIT_LIST_HEAD(&uobj->async_list);
632 
633 	cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
634 					     file->ucontext, &udata);
635 	if (IS_ERR(cq)) {
636 		ret = PTR_ERR(cq);
637 		goto err;
638 	}
639 
640 	cq->device        = file->device->ib_dev;
641 	cq->uobject       = &uobj->uobject;
642 	cq->comp_handler  = ib_uverbs_comp_handler;
643 	cq->event_handler = ib_uverbs_cq_event_handler;
644 	cq->cq_context    = file;
645 	atomic_set(&cq->usecnt, 0);
646 
647 retry:
648 	if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
649 		ret = -ENOMEM;
650 		goto err_cq;
651 	}
652 
653 	down(&ib_uverbs_idr_mutex);
654 	ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id);
655 	up(&ib_uverbs_idr_mutex);
656 
657 	if (ret == -EAGAIN)
658 		goto retry;
659 	if (ret)
660 		goto err_cq;
661 
662 	down(&file->mutex);
663 	list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
664 	up(&file->mutex);
665 
666 	memset(&resp, 0, sizeof resp);
667 	resp.cq_handle = uobj->uobject.id;
668 	resp.cqe       = cq->cqe;
669 
670 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
671 			 &resp, sizeof resp)) {
672 		ret = -EFAULT;
673 		goto err_list;
674 	}
675 
676 	return in_len;
677 
678 err_list:
679  	down(&file->mutex);
680 	list_del(&uobj->uobject.list);
681 	up(&file->mutex);
682 
683 	down(&ib_uverbs_idr_mutex);
684 	idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
685 	up(&ib_uverbs_idr_mutex);
686 
687 err_cq:
688 	ib_destroy_cq(cq);
689 
690 err:
691 	kfree(uobj);
692 	return ret;
693 }
694 
695 ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
696 			     const char __user *buf, int in_len,
697 			     int out_len)
698 {
699 	struct ib_uverbs_destroy_cq      cmd;
700 	struct ib_uverbs_destroy_cq_resp resp;
701 	struct ib_cq               	*cq;
702 	struct ib_ucq_object        	*uobj;
703 	struct ib_uverbs_event		*evt, *tmp;
704 	u64				 user_handle;
705 	int                        	 ret = -EINVAL;
706 
707 	if (copy_from_user(&cmd, buf, sizeof cmd))
708 		return -EFAULT;
709 
710 	memset(&resp, 0, sizeof resp);
711 
712 	down(&ib_uverbs_idr_mutex);
713 
714 	cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
715 	if (!cq || cq->uobject->context != file->ucontext)
716 		goto out;
717 
718 	user_handle = cq->uobject->user_handle;
719 	uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
720 
721 	ret = ib_destroy_cq(cq);
722 	if (ret)
723 		goto out;
724 
725 	idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
726 
727 	down(&file->mutex);
728 	list_del(&uobj->uobject.list);
729 	up(&file->mutex);
730 
731 	spin_lock_irq(&file->comp_file[0].lock);
732 	list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
733 		list_del(&evt->list);
734 		kfree(evt);
735 	}
736 	spin_unlock_irq(&file->comp_file[0].lock);
737 
738 	spin_lock_irq(&file->async_file.lock);
739 	list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) {
740 		list_del(&evt->list);
741 		kfree(evt);
742 	}
743 	spin_unlock_irq(&file->async_file.lock);
744 
745 	resp.comp_events_reported  = uobj->comp_events_reported;
746 	resp.async_events_reported = uobj->async_events_reported;
747 
748 	kfree(uobj);
749 
750 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
751 			 &resp, sizeof resp))
752 		ret = -EFAULT;
753 
754 out:
755 	up(&ib_uverbs_idr_mutex);
756 
757 	return ret ? ret : in_len;
758 }
759 
760 ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
761 			    const char __user *buf, int in_len,
762 			    int out_len)
763 {
764 	struct ib_uverbs_create_qp      cmd;
765 	struct ib_uverbs_create_qp_resp resp;
766 	struct ib_udata                 udata;
767 	struct ib_uevent_object        *uobj;
768 	struct ib_pd                   *pd;
769 	struct ib_cq                   *scq, *rcq;
770 	struct ib_srq                  *srq;
771 	struct ib_qp                   *qp;
772 	struct ib_qp_init_attr          attr;
773 	int ret;
774 
775 	if (out_len < sizeof resp)
776 		return -ENOSPC;
777 
778 	if (copy_from_user(&cmd, buf, sizeof cmd))
779 		return -EFAULT;
780 
781 	INIT_UDATA(&udata, buf + sizeof cmd,
782 		   (unsigned long) cmd.response + sizeof resp,
783 		   in_len - sizeof cmd, out_len - sizeof resp);
784 
785 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
786 	if (!uobj)
787 		return -ENOMEM;
788 
789 	down(&ib_uverbs_idr_mutex);
790 
791 	pd  = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
792 	scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
793 	rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
794 	srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL;
795 
796 	if (!pd  || pd->uobject->context  != file->ucontext ||
797 	    !scq || scq->uobject->context != file->ucontext ||
798 	    !rcq || rcq->uobject->context != file->ucontext ||
799 	    (cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) {
800 		ret = -EINVAL;
801 		goto err_up;
802 	}
803 
804 	attr.event_handler = ib_uverbs_qp_event_handler;
805 	attr.qp_context    = file;
806 	attr.send_cq       = scq;
807 	attr.recv_cq       = rcq;
808 	attr.srq           = srq;
809 	attr.sq_sig_type   = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
810 	attr.qp_type       = cmd.qp_type;
811 
812 	attr.cap.max_send_wr     = cmd.max_send_wr;
813 	attr.cap.max_recv_wr     = cmd.max_recv_wr;
814 	attr.cap.max_send_sge    = cmd.max_send_sge;
815 	attr.cap.max_recv_sge    = cmd.max_recv_sge;
816 	attr.cap.max_inline_data = cmd.max_inline_data;
817 
818 	uobj->uobject.user_handle = cmd.user_handle;
819 	uobj->uobject.context     = file->ucontext;
820 	uobj->events_reported     = 0;
821 	INIT_LIST_HEAD(&uobj->event_list);
822 
823 	qp = pd->device->create_qp(pd, &attr, &udata);
824 	if (IS_ERR(qp)) {
825 		ret = PTR_ERR(qp);
826 		goto err_up;
827 	}
828 
829 	qp->device     	  = pd->device;
830 	qp->pd         	  = pd;
831 	qp->send_cq    	  = attr.send_cq;
832 	qp->recv_cq    	  = attr.recv_cq;
833 	qp->srq	       	  = attr.srq;
834 	qp->uobject       = &uobj->uobject;
835 	qp->event_handler = attr.event_handler;
836 	qp->qp_context    = attr.qp_context;
837 	qp->qp_type	  = attr.qp_type;
838 	atomic_inc(&pd->usecnt);
839 	atomic_inc(&attr.send_cq->usecnt);
840 	atomic_inc(&attr.recv_cq->usecnt);
841 	if (attr.srq)
842 		atomic_inc(&attr.srq->usecnt);
843 
844 	memset(&resp, 0, sizeof resp);
845 	resp.qpn = qp->qp_num;
846 
847 retry:
848 	if (!idr_pre_get(&ib_uverbs_qp_idr, GFP_KERNEL)) {
849 		ret = -ENOMEM;
850 		goto err_destroy;
851 	}
852 
853 	ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->uobject.id);
854 
855 	if (ret == -EAGAIN)
856 		goto retry;
857 	if (ret)
858 		goto err_destroy;
859 
860 	resp.qp_handle = uobj->uobject.id;
861 
862 	down(&file->mutex);
863 	list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
864 	up(&file->mutex);
865 
866 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
867 			 &resp, sizeof resp)) {
868 		ret = -EFAULT;
869 		goto err_list;
870 	}
871 
872 	up(&ib_uverbs_idr_mutex);
873 
874 	return in_len;
875 
876 err_list:
877 	down(&file->mutex);
878 	list_del(&uobj->uobject.list);
879 	up(&file->mutex);
880 
881 err_destroy:
882 	ib_destroy_qp(qp);
883 
884 err_up:
885 	up(&ib_uverbs_idr_mutex);
886 
887 	kfree(uobj);
888 	return ret;
889 }
890 
891 ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
892 			    const char __user *buf, int in_len,
893 			    int out_len)
894 {
895 	struct ib_uverbs_modify_qp cmd;
896 	struct ib_qp              *qp;
897 	struct ib_qp_attr         *attr;
898 	int                        ret;
899 
900 	if (copy_from_user(&cmd, buf, sizeof cmd))
901 		return -EFAULT;
902 
903 	attr = kmalloc(sizeof *attr, GFP_KERNEL);
904 	if (!attr)
905 		return -ENOMEM;
906 
907 	down(&ib_uverbs_idr_mutex);
908 
909 	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
910 	if (!qp || qp->uobject->context != file->ucontext) {
911 		ret = -EINVAL;
912 		goto out;
913 	}
914 
915 	attr->qp_state 		  = cmd.qp_state;
916 	attr->cur_qp_state 	  = cmd.cur_qp_state;
917 	attr->path_mtu 		  = cmd.path_mtu;
918 	attr->path_mig_state 	  = cmd.path_mig_state;
919 	attr->qkey 		  = cmd.qkey;
920 	attr->rq_psn 		  = cmd.rq_psn;
921 	attr->sq_psn 		  = cmd.sq_psn;
922 	attr->dest_qp_num 	  = cmd.dest_qp_num;
923 	attr->qp_access_flags 	  = cmd.qp_access_flags;
924 	attr->pkey_index 	  = cmd.pkey_index;
925 	attr->alt_pkey_index 	  = cmd.pkey_index;
926 	attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
927 	attr->max_rd_atomic 	  = cmd.max_rd_atomic;
928 	attr->max_dest_rd_atomic  = cmd.max_dest_rd_atomic;
929 	attr->min_rnr_timer 	  = cmd.min_rnr_timer;
930 	attr->port_num 		  = cmd.port_num;
931 	attr->timeout 		  = cmd.timeout;
932 	attr->retry_cnt 	  = cmd.retry_cnt;
933 	attr->rnr_retry 	  = cmd.rnr_retry;
934 	attr->alt_port_num 	  = cmd.alt_port_num;
935 	attr->alt_timeout 	  = cmd.alt_timeout;
936 
937 	memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
938 	attr->ah_attr.grh.flow_label        = cmd.dest.flow_label;
939 	attr->ah_attr.grh.sgid_index        = cmd.dest.sgid_index;
940 	attr->ah_attr.grh.hop_limit         = cmd.dest.hop_limit;
941 	attr->ah_attr.grh.traffic_class     = cmd.dest.traffic_class;
942 	attr->ah_attr.dlid 	    	    = cmd.dest.dlid;
943 	attr->ah_attr.sl   	    	    = cmd.dest.sl;
944 	attr->ah_attr.src_path_bits 	    = cmd.dest.src_path_bits;
945 	attr->ah_attr.static_rate   	    = cmd.dest.static_rate;
946 	attr->ah_attr.ah_flags 	    	    = cmd.dest.is_global ? IB_AH_GRH : 0;
947 	attr->ah_attr.port_num 	    	    = cmd.dest.port_num;
948 
949 	memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
950 	attr->alt_ah_attr.grh.flow_label    = cmd.alt_dest.flow_label;
951 	attr->alt_ah_attr.grh.sgid_index    = cmd.alt_dest.sgid_index;
952 	attr->alt_ah_attr.grh.hop_limit     = cmd.alt_dest.hop_limit;
953 	attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
954 	attr->alt_ah_attr.dlid 	    	    = cmd.alt_dest.dlid;
955 	attr->alt_ah_attr.sl   	    	    = cmd.alt_dest.sl;
956 	attr->alt_ah_attr.src_path_bits     = cmd.alt_dest.src_path_bits;
957 	attr->alt_ah_attr.static_rate       = cmd.alt_dest.static_rate;
958 	attr->alt_ah_attr.ah_flags 	    = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
959 	attr->alt_ah_attr.port_num 	    = cmd.alt_dest.port_num;
960 
961 	ret = ib_modify_qp(qp, attr, cmd.attr_mask);
962 	if (ret)
963 		goto out;
964 
965 	ret = in_len;
966 
967 out:
968 	up(&ib_uverbs_idr_mutex);
969 	kfree(attr);
970 
971 	return ret;
972 }
973 
974 ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
975 			     const char __user *buf, int in_len,
976 			     int out_len)
977 {
978 	struct ib_uverbs_destroy_qp      cmd;
979 	struct ib_uverbs_destroy_qp_resp resp;
980 	struct ib_qp               	*qp;
981 	struct ib_uevent_object        	*uobj;
982 	struct ib_uverbs_event		*evt, *tmp;
983 	int                        	 ret = -EINVAL;
984 
985 	if (copy_from_user(&cmd, buf, sizeof cmd))
986 		return -EFAULT;
987 
988 	memset(&resp, 0, sizeof resp);
989 
990 	down(&ib_uverbs_idr_mutex);
991 
992 	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
993 	if (!qp || qp->uobject->context != file->ucontext)
994 		goto out;
995 
996 	uobj = container_of(qp->uobject, struct ib_uevent_object, uobject);
997 
998 	ret = ib_destroy_qp(qp);
999 	if (ret)
1000 		goto out;
1001 
1002 	idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
1003 
1004 	down(&file->mutex);
1005 	list_del(&uobj->uobject.list);
1006 	up(&file->mutex);
1007 
1008 	spin_lock_irq(&file->async_file.lock);
1009 	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
1010 		list_del(&evt->list);
1011 		kfree(evt);
1012 	}
1013 	spin_unlock_irq(&file->async_file.lock);
1014 
1015 	resp.events_reported = uobj->events_reported;
1016 
1017 	kfree(uobj);
1018 
1019 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
1020 			 &resp, sizeof resp))
1021 		ret = -EFAULT;
1022 
1023 out:
1024 	up(&ib_uverbs_idr_mutex);
1025 
1026 	return ret ? ret : in_len;
1027 }
1028 
1029 ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
1030 			       const char __user *buf, int in_len,
1031 			       int out_len)
1032 {
1033 	struct ib_uverbs_attach_mcast cmd;
1034 	struct ib_qp                 *qp;
1035 	int                           ret = -EINVAL;
1036 
1037 	if (copy_from_user(&cmd, buf, sizeof cmd))
1038 		return -EFAULT;
1039 
1040 	down(&ib_uverbs_idr_mutex);
1041 
1042 	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1043 	if (qp && qp->uobject->context == file->ucontext)
1044 		ret = ib_attach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
1045 
1046 	up(&ib_uverbs_idr_mutex);
1047 
1048 	return ret ? ret : in_len;
1049 }
1050 
1051 ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1052 			       const char __user *buf, int in_len,
1053 			       int out_len)
1054 {
1055 	struct ib_uverbs_detach_mcast cmd;
1056 	struct ib_qp                 *qp;
1057 	int                           ret = -EINVAL;
1058 
1059 	if (copy_from_user(&cmd, buf, sizeof cmd))
1060 		return -EFAULT;
1061 
1062 	down(&ib_uverbs_idr_mutex);
1063 
1064 	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1065 	if (qp && qp->uobject->context == file->ucontext)
1066 		ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
1067 
1068 	up(&ib_uverbs_idr_mutex);
1069 
1070 	return ret ? ret : in_len;
1071 }
1072 
1073 ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
1074 			     const char __user *buf, int in_len,
1075 			     int out_len)
1076 {
1077 	struct ib_uverbs_create_srq      cmd;
1078 	struct ib_uverbs_create_srq_resp resp;
1079 	struct ib_udata                  udata;
1080 	struct ib_uevent_object         *uobj;
1081 	struct ib_pd                    *pd;
1082 	struct ib_srq                   *srq;
1083 	struct ib_srq_init_attr          attr;
1084 	int ret;
1085 
1086 	if (out_len < sizeof resp)
1087 		return -ENOSPC;
1088 
1089 	if (copy_from_user(&cmd, buf, sizeof cmd))
1090 		return -EFAULT;
1091 
1092 	INIT_UDATA(&udata, buf + sizeof cmd,
1093 		   (unsigned long) cmd.response + sizeof resp,
1094 		   in_len - sizeof cmd, out_len - sizeof resp);
1095 
1096 	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
1097 	if (!uobj)
1098 		return -ENOMEM;
1099 
1100 	down(&ib_uverbs_idr_mutex);
1101 
1102 	pd  = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
1103 
1104 	if (!pd || pd->uobject->context != file->ucontext) {
1105 		ret = -EINVAL;
1106 		goto err_up;
1107 	}
1108 
1109 	attr.event_handler  = ib_uverbs_srq_event_handler;
1110 	attr.srq_context    = file;
1111 	attr.attr.max_wr    = cmd.max_wr;
1112 	attr.attr.max_sge   = cmd.max_sge;
1113 	attr.attr.srq_limit = cmd.srq_limit;
1114 
1115 	uobj->uobject.user_handle = cmd.user_handle;
1116 	uobj->uobject.context     = file->ucontext;
1117 	uobj->events_reported     = 0;
1118 	INIT_LIST_HEAD(&uobj->event_list);
1119 
1120 	srq = pd->device->create_srq(pd, &attr, &udata);
1121 	if (IS_ERR(srq)) {
1122 		ret = PTR_ERR(srq);
1123 		goto err_up;
1124 	}
1125 
1126 	srq->device    	   = pd->device;
1127 	srq->pd        	   = pd;
1128 	srq->uobject       = &uobj->uobject;
1129 	srq->event_handler = attr.event_handler;
1130 	srq->srq_context   = attr.srq_context;
1131 	atomic_inc(&pd->usecnt);
1132 	atomic_set(&srq->usecnt, 0);
1133 
1134 	memset(&resp, 0, sizeof resp);
1135 
1136 retry:
1137 	if (!idr_pre_get(&ib_uverbs_srq_idr, GFP_KERNEL)) {
1138 		ret = -ENOMEM;
1139 		goto err_destroy;
1140 	}
1141 
1142 	ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->uobject.id);
1143 
1144 	if (ret == -EAGAIN)
1145 		goto retry;
1146 	if (ret)
1147 		goto err_destroy;
1148 
1149 	resp.srq_handle = uobj->uobject.id;
1150 
1151 	down(&file->mutex);
1152 	list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
1153 	up(&file->mutex);
1154 
1155 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
1156 			 &resp, sizeof resp)) {
1157 		ret = -EFAULT;
1158 		goto err_list;
1159 	}
1160 
1161 	up(&ib_uverbs_idr_mutex);
1162 
1163 	return in_len;
1164 
1165 err_list:
1166 	down(&file->mutex);
1167 	list_del(&uobj->uobject.list);
1168 	up(&file->mutex);
1169 
1170 err_destroy:
1171 	ib_destroy_srq(srq);
1172 
1173 err_up:
1174 	up(&ib_uverbs_idr_mutex);
1175 
1176 	kfree(uobj);
1177 	return ret;
1178 }
1179 
1180 ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1181 			     const char __user *buf, int in_len,
1182 			     int out_len)
1183 {
1184 	struct ib_uverbs_modify_srq cmd;
1185 	struct ib_srq              *srq;
1186 	struct ib_srq_attr          attr;
1187 	int                         ret;
1188 
1189 	if (copy_from_user(&cmd, buf, sizeof cmd))
1190 		return -EFAULT;
1191 
1192 	down(&ib_uverbs_idr_mutex);
1193 
1194 	srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1195 	if (!srq || srq->uobject->context != file->ucontext) {
1196 		ret = -EINVAL;
1197 		goto out;
1198 	}
1199 
1200 	attr.max_wr    = cmd.max_wr;
1201 	attr.max_sge   = cmd.max_sge;
1202 	attr.srq_limit = cmd.srq_limit;
1203 
1204 	ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
1205 
1206 out:
1207 	up(&ib_uverbs_idr_mutex);
1208 
1209 	return ret ? ret : in_len;
1210 }
1211 
1212 ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
1213 			      const char __user *buf, int in_len,
1214 			      int out_len)
1215 {
1216 	struct ib_uverbs_destroy_srq      cmd;
1217 	struct ib_uverbs_destroy_srq_resp resp;
1218 	struct ib_srq               	 *srq;
1219 	struct ib_uevent_object        	 *uobj;
1220 	struct ib_uverbs_event		 *evt, *tmp;
1221 	int                         	  ret = -EINVAL;
1222 
1223 	if (copy_from_user(&cmd, buf, sizeof cmd))
1224 		return -EFAULT;
1225 
1226 	down(&ib_uverbs_idr_mutex);
1227 
1228 	memset(&resp, 0, sizeof resp);
1229 
1230 	srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1231 	if (!srq || srq->uobject->context != file->ucontext)
1232 		goto out;
1233 
1234 	uobj = container_of(srq->uobject, struct ib_uevent_object, uobject);
1235 
1236 	ret = ib_destroy_srq(srq);
1237 	if (ret)
1238 		goto out;
1239 
1240 	idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
1241 
1242 	down(&file->mutex);
1243 	list_del(&uobj->uobject.list);
1244 	up(&file->mutex);
1245 
1246 	spin_lock_irq(&file->async_file.lock);
1247 	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
1248 		list_del(&evt->list);
1249 		kfree(evt);
1250 	}
1251 	spin_unlock_irq(&file->async_file.lock);
1252 
1253 	resp.events_reported = uobj->events_reported;
1254 
1255 	kfree(uobj);
1256 
1257 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
1258 			 &resp, sizeof resp))
1259 		ret = -EFAULT;
1260 
1261 out:
1262 	up(&ib_uverbs_idr_mutex);
1263 
1264 	return ret ? ret : in_len;
1265 }
1266