]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/infiniband/core/uverbs_cmd.c
IB/uverbs: Release lock on error path
[mv-sheeva.git] / drivers / infiniband / core / uverbs_cmd.c
1 /*
2  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
4  * Copyright (c) 2005 PathScale, Inc.  All rights reserved.
5  * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.
6  *
7  * This software is available to you under a choice of one of two
8  * licenses.  You may choose to be licensed under the terms of the GNU
9  * General Public License (GPL) Version 2, available from the file
10  * COPYING in the main directory of this source tree, or the
11  * OpenIB.org BSD license below:
12  *
13  *     Redistribution and use in source and binary forms, with or
14  *     without modification, are permitted provided that the following
15  *     conditions are met:
16  *
17  *      - Redistributions of source code must retain the above
18  *        copyright notice, this list of conditions and the following
19  *        disclaimer.
20  *
21  *      - Redistributions in binary form must reproduce the above
22  *        copyright notice, this list of conditions and the following
23  *        disclaimer in the documentation and/or other materials
24  *        provided with the distribution.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33  * SOFTWARE.
34  *
35  * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
36  */
37
38 #include <linux/file.h>
39 #include <linux/fs.h>
40
41 #include <asm/uaccess.h>
42
43 #include "uverbs.h"
44
45 #define INIT_UDATA(udata, ibuf, obuf, ilen, olen)                       \
46         do {                                                            \
47                 (udata)->inbuf  = (void __user *) (ibuf);               \
48                 (udata)->outbuf = (void __user *) (obuf);               \
49                 (udata)->inlen  = (ilen);                               \
50                 (udata)->outlen = (olen);                               \
51         } while (0)
52
53 ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
54                               const char __user *buf,
55                               int in_len, int out_len)
56 {
57         struct ib_uverbs_get_context      cmd;
58         struct ib_uverbs_get_context_resp resp;
59         struct ib_udata                   udata;
60         struct ib_device                 *ibdev = file->device->ib_dev;
61         struct ib_ucontext               *ucontext;
62         struct file                      *filp;
63         int ret;
64
65         if (out_len < sizeof resp)
66                 return -ENOSPC;
67
68         if (copy_from_user(&cmd, buf, sizeof cmd))
69                 return -EFAULT;
70
71         mutex_lock(&file->mutex);
72
73         if (file->ucontext) {
74                 ret = -EINVAL;
75                 goto err;
76         }
77
78         INIT_UDATA(&udata, buf + sizeof cmd,
79                    (unsigned long) cmd.response + sizeof resp,
80                    in_len - sizeof cmd, out_len - sizeof resp);
81
82         ucontext = ibdev->alloc_ucontext(ibdev, &udata);
83         if (IS_ERR(ucontext)) {
84                 ret = PTR_ERR(file->ucontext);
85                 goto err;
86         }
87
88         ucontext->device = ibdev;
89         INIT_LIST_HEAD(&ucontext->pd_list);
90         INIT_LIST_HEAD(&ucontext->mr_list);
91         INIT_LIST_HEAD(&ucontext->mw_list);
92         INIT_LIST_HEAD(&ucontext->cq_list);
93         INIT_LIST_HEAD(&ucontext->qp_list);
94         INIT_LIST_HEAD(&ucontext->srq_list);
95         INIT_LIST_HEAD(&ucontext->ah_list);
96
97         resp.num_comp_vectors = file->device->num_comp_vectors;
98
99         filp = ib_uverbs_alloc_event_file(file, 1, &resp.async_fd);
100         if (IS_ERR(filp)) {
101                 ret = PTR_ERR(filp);
102                 goto err_free;
103         }
104
105         if (copy_to_user((void __user *) (unsigned long) cmd.response,
106                          &resp, sizeof resp)) {
107                 ret = -EFAULT;
108                 goto err_file;
109         }
110
111         file->async_file = filp->private_data;
112
113         INIT_IB_EVENT_HANDLER(&file->event_handler, file->device->ib_dev,
114                               ib_uverbs_event_handler);
115         ret = ib_register_event_handler(&file->event_handler);
116         if (ret)
117                 goto err_file;
118
119         kref_get(&file->async_file->ref);
120         kref_get(&file->ref);
121         file->ucontext = ucontext;
122
123         fd_install(resp.async_fd, filp);
124
125         mutex_unlock(&file->mutex);
126
127         return in_len;
128
129 err_file:
130         put_unused_fd(resp.async_fd);
131         fput(filp);
132
133 err_free:
134         ibdev->dealloc_ucontext(ucontext);
135
136 err:
137         mutex_unlock(&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                 = file->device->ib_dev->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_alloc_pd(struct ib_uverbs_file *file,
259                            const char __user *buf,
260                            int in_len, int out_len)
261 {
262         struct ib_uverbs_alloc_pd      cmd;
263         struct ib_uverbs_alloc_pd_resp resp;
264         struct ib_udata                udata;
265         struct ib_uobject             *uobj;
266         struct ib_pd                  *pd;
267         int                            ret;
268
269         if (out_len < sizeof resp)
270                 return -ENOSPC;
271
272         if (copy_from_user(&cmd, buf, sizeof cmd))
273                 return -EFAULT;
274
275         INIT_UDATA(&udata, buf + sizeof cmd,
276                    (unsigned long) cmd.response + sizeof resp,
277                    in_len - sizeof cmd, out_len - sizeof resp);
278
279         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
280         if (!uobj)
281                 return -ENOMEM;
282
283         uobj->context = file->ucontext;
284
285         pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
286                                             file->ucontext, &udata);
287         if (IS_ERR(pd)) {
288                 ret = PTR_ERR(pd);
289                 goto err;
290         }
291
292         pd->device  = file->device->ib_dev;
293         pd->uobject = uobj;
294         atomic_set(&pd->usecnt, 0);
295
296         mutex_lock(&ib_uverbs_idr_mutex);
297
298 retry:
299         if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
300                 ret = -ENOMEM;
301                 goto err_up;
302         }
303
304         ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id);
305
306         if (ret == -EAGAIN)
307                 goto retry;
308         if (ret)
309                 goto err_up;
310
311         memset(&resp, 0, sizeof resp);
312         resp.pd_handle = uobj->id;
313
314         if (copy_to_user((void __user *) (unsigned long) cmd.response,
315                          &resp, sizeof resp)) {
316                 ret = -EFAULT;
317                 goto err_idr;
318         }
319
320         mutex_lock(&file->mutex);
321         list_add_tail(&uobj->list, &file->ucontext->pd_list);
322         mutex_unlock(&file->mutex);
323
324         mutex_unlock(&ib_uverbs_idr_mutex);
325
326         return in_len;
327
328 err_idr:
329         idr_remove(&ib_uverbs_pd_idr, uobj->id);
330
331 err_up:
332         mutex_unlock(&ib_uverbs_idr_mutex);
333         ib_dealloc_pd(pd);
334
335 err:
336         kfree(uobj);
337         return ret;
338 }
339
340 ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
341                              const char __user *buf,
342                              int in_len, int out_len)
343 {
344         struct ib_uverbs_dealloc_pd cmd;
345         struct ib_pd               *pd;
346         struct ib_uobject          *uobj;
347         int                         ret = -EINVAL;
348
349         if (copy_from_user(&cmd, buf, sizeof cmd))
350                 return -EFAULT;
351
352         mutex_lock(&ib_uverbs_idr_mutex);
353
354         pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
355         if (!pd || pd->uobject->context != file->ucontext)
356                 goto out;
357
358         uobj = pd->uobject;
359
360         ret = ib_dealloc_pd(pd);
361         if (ret)
362                 goto out;
363
364         idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
365
366         mutex_lock(&file->mutex);
367         list_del(&uobj->list);
368         mutex_unlock(&file->mutex);
369
370         kfree(uobj);
371
372 out:
373         mutex_unlock(&ib_uverbs_idr_mutex);
374
375         return ret ? ret : in_len;
376 }
377
378 ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
379                          const char __user *buf, int in_len,
380                          int out_len)
381 {
382         struct ib_uverbs_reg_mr      cmd;
383         struct ib_uverbs_reg_mr_resp resp;
384         struct ib_udata              udata;
385         struct ib_umem_object       *obj;
386         struct ib_pd                *pd;
387         struct ib_mr                *mr;
388         int                          ret;
389
390         if (out_len < sizeof resp)
391                 return -ENOSPC;
392
393         if (copy_from_user(&cmd, buf, sizeof cmd))
394                 return -EFAULT;
395
396         INIT_UDATA(&udata, buf + sizeof cmd,
397                    (unsigned long) cmd.response + sizeof resp,
398                    in_len - sizeof cmd, out_len - sizeof resp);
399
400         if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
401                 return -EINVAL;
402
403         /*
404          * Local write permission is required if remote write or
405          * remote atomic permission is also requested.
406          */
407         if (cmd.access_flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) &&
408             !(cmd.access_flags & IB_ACCESS_LOCAL_WRITE))
409                 return -EINVAL;
410
411         obj = kmalloc(sizeof *obj, GFP_KERNEL);
412         if (!obj)
413                 return -ENOMEM;
414
415         obj->uobject.context = file->ucontext;
416
417         /*
418          * We ask for writable memory if any access flags other than
419          * "remote read" are set.  "Local write" and "remote write"
420          * obviously require write access.  "Remote atomic" can do
421          * things like fetch and add, which will modify memory, and
422          * "MW bind" can change permissions by binding a window.
423          */
424         ret = ib_umem_get(file->device->ib_dev, &obj->umem,
425                           (void *) (unsigned long) cmd.start, cmd.length,
426                           !!(cmd.access_flags & ~IB_ACCESS_REMOTE_READ));
427         if (ret)
428                 goto err_free;
429
430         obj->umem.virt_base = cmd.hca_va;
431
432         mutex_lock(&ib_uverbs_idr_mutex);
433
434         pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
435         if (!pd || pd->uobject->context != file->ucontext) {
436                 ret = -EINVAL;
437                 goto err_up;
438         }
439
440         if (!pd->device->reg_user_mr) {
441                 ret = -ENOSYS;
442                 goto err_up;
443         }
444
445         mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata);
446         if (IS_ERR(mr)) {
447                 ret = PTR_ERR(mr);
448                 goto err_up;
449         }
450
451         mr->device  = pd->device;
452         mr->pd      = pd;
453         mr->uobject = &obj->uobject;
454         atomic_inc(&pd->usecnt);
455         atomic_set(&mr->usecnt, 0);
456
457         memset(&resp, 0, sizeof resp);
458         resp.lkey = mr->lkey;
459         resp.rkey = mr->rkey;
460
461 retry:
462         if (!idr_pre_get(&ib_uverbs_mr_idr, GFP_KERNEL)) {
463                 ret = -ENOMEM;
464                 goto err_unreg;
465         }
466
467         ret = idr_get_new(&ib_uverbs_mr_idr, mr, &obj->uobject.id);
468
469         if (ret == -EAGAIN)
470                 goto retry;
471         if (ret)
472                 goto err_unreg;
473
474         resp.mr_handle = obj->uobject.id;
475
476         if (copy_to_user((void __user *) (unsigned long) cmd.response,
477                          &resp, sizeof resp)) {
478                 ret = -EFAULT;
479                 goto err_idr;
480         }
481
482         mutex_lock(&file->mutex);
483         list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
484         mutex_unlock(&file->mutex);
485
486         mutex_unlock(&ib_uverbs_idr_mutex);
487
488         return in_len;
489
490 err_idr:
491         idr_remove(&ib_uverbs_mr_idr, obj->uobject.id);
492
493 err_unreg:
494         ib_dereg_mr(mr);
495         atomic_dec(&pd->usecnt);
496
497 err_up:
498         mutex_unlock(&ib_uverbs_idr_mutex);
499
500         ib_umem_release(file->device->ib_dev, &obj->umem);
501
502 err_free:
503         kfree(obj);
504         return ret;
505 }
506
507 ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
508                            const char __user *buf, int in_len,
509                            int out_len)
510 {
511         struct ib_uverbs_dereg_mr cmd;
512         struct ib_mr             *mr;
513         struct ib_umem_object    *memobj;
514         int                       ret = -EINVAL;
515
516         if (copy_from_user(&cmd, buf, sizeof cmd))
517                 return -EFAULT;
518
519         mutex_lock(&ib_uverbs_idr_mutex);
520
521         mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle);
522         if (!mr || mr->uobject->context != file->ucontext)
523                 goto out;
524
525         memobj = container_of(mr->uobject, struct ib_umem_object, uobject);
526
527         ret = ib_dereg_mr(mr);
528         if (ret)
529                 goto out;
530
531         idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
532
533         mutex_lock(&file->mutex);
534         list_del(&memobj->uobject.list);
535         mutex_unlock(&file->mutex);
536
537         ib_umem_release(file->device->ib_dev, &memobj->umem);
538         kfree(memobj);
539
540 out:
541         mutex_unlock(&ib_uverbs_idr_mutex);
542
543         return ret ? ret : in_len;
544 }
545
546 ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
547                                       const char __user *buf, int in_len,
548                                       int out_len)
549 {
550         struct ib_uverbs_create_comp_channel       cmd;
551         struct ib_uverbs_create_comp_channel_resp  resp;
552         struct file                               *filp;
553
554         if (out_len < sizeof resp)
555                 return -ENOSPC;
556
557         if (copy_from_user(&cmd, buf, sizeof cmd))
558                 return -EFAULT;
559
560         filp = ib_uverbs_alloc_event_file(file, 0, &resp.fd);
561         if (IS_ERR(filp))
562                 return PTR_ERR(filp);
563
564         if (copy_to_user((void __user *) (unsigned long) cmd.response,
565                          &resp, sizeof resp)) {
566                 put_unused_fd(resp.fd);
567                 fput(filp);
568                 return -EFAULT;
569         }
570
571         fd_install(resp.fd, filp);
572         return in_len;
573 }
574
575 ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
576                             const char __user *buf, int in_len,
577                             int out_len)
578 {
579         struct ib_uverbs_create_cq      cmd;
580         struct ib_uverbs_create_cq_resp resp;
581         struct ib_udata                 udata;
582         struct ib_ucq_object           *uobj;
583         struct ib_uverbs_event_file    *ev_file = NULL;
584         struct ib_cq                   *cq;
585         int                             ret;
586
587         if (out_len < sizeof resp)
588                 return -ENOSPC;
589
590         if (copy_from_user(&cmd, buf, sizeof cmd))
591                 return -EFAULT;
592
593         INIT_UDATA(&udata, buf + sizeof cmd,
594                    (unsigned long) cmd.response + sizeof resp,
595                    in_len - sizeof cmd, out_len - sizeof resp);
596
597         if (cmd.comp_vector >= file->device->num_comp_vectors)
598                 return -EINVAL;
599
600         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
601         if (!uobj)
602                 return -ENOMEM;
603
604         if (cmd.comp_channel >= 0) {
605                 ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel);
606                 if (!ev_file) {
607                         ret = -EINVAL;
608                         goto err;
609                 }
610         }
611
612         uobj->uobject.user_handle   = cmd.user_handle;
613         uobj->uobject.context       = file->ucontext;
614         uobj->uverbs_file           = file;
615         uobj->comp_events_reported  = 0;
616         uobj->async_events_reported = 0;
617         INIT_LIST_HEAD(&uobj->comp_list);
618         INIT_LIST_HEAD(&uobj->async_list);
619
620         cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
621                                              file->ucontext, &udata);
622         if (IS_ERR(cq)) {
623                 ret = PTR_ERR(cq);
624                 goto err;
625         }
626
627         cq->device        = file->device->ib_dev;
628         cq->uobject       = &uobj->uobject;
629         cq->comp_handler  = ib_uverbs_comp_handler;
630         cq->event_handler = ib_uverbs_cq_event_handler;
631         cq->cq_context    = ev_file;
632         atomic_set(&cq->usecnt, 0);
633
634         mutex_lock(&ib_uverbs_idr_mutex);
635
636 retry:
637         if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
638                 ret = -ENOMEM;
639                 goto err_up;
640         }
641
642         ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->uobject.id);
643
644         if (ret == -EAGAIN)
645                 goto retry;
646         if (ret)
647                 goto err_up;
648
649         memset(&resp, 0, sizeof resp);
650         resp.cq_handle = uobj->uobject.id;
651         resp.cqe       = cq->cqe;
652
653         if (copy_to_user((void __user *) (unsigned long) cmd.response,
654                          &resp, sizeof resp)) {
655                 ret = -EFAULT;
656                 goto err_idr;
657         }
658
659         mutex_lock(&file->mutex);
660         list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
661         mutex_unlock(&file->mutex);
662
663         mutex_unlock(&ib_uverbs_idr_mutex);
664
665         return in_len;
666
667 err_idr:
668         idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
669
670 err_up:
671         mutex_unlock(&ib_uverbs_idr_mutex);
672         ib_destroy_cq(cq);
673
674 err:
675         if (ev_file)
676                 ib_uverbs_release_ucq(file, ev_file, uobj);
677         kfree(uobj);
678         return ret;
679 }
680
681 ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
682                             const char __user *buf, int in_len,
683                             int out_len)
684 {
685         struct ib_uverbs_resize_cq      cmd;
686         struct ib_uverbs_resize_cq_resp resp;
687         struct ib_udata                 udata;
688         struct ib_cq                    *cq;
689         int                             ret = -EINVAL;
690
691         if (copy_from_user(&cmd, buf, sizeof cmd))
692                 return -EFAULT;
693
694         INIT_UDATA(&udata, buf + sizeof cmd,
695                    (unsigned long) cmd.response + sizeof resp,
696                    in_len - sizeof cmd, out_len - sizeof resp);
697
698         mutex_lock(&ib_uverbs_idr_mutex);
699
700         cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
701         if (!cq || cq->uobject->context != file->ucontext || !cq->device->resize_cq)
702                 goto out;
703
704         ret = cq->device->resize_cq(cq, cmd.cqe, &udata);
705         if (ret)
706                 goto out;
707
708         memset(&resp, 0, sizeof resp);
709         resp.cqe = cq->cqe;
710
711         if (copy_to_user((void __user *) (unsigned long) cmd.response,
712                          &resp, sizeof resp))
713                 ret = -EFAULT;
714
715 out:
716         mutex_unlock(&ib_uverbs_idr_mutex);
717
718         return ret ? ret : in_len;
719 }
720
721 ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
722                           const char __user *buf, int in_len,
723                           int out_len)
724 {
725         struct ib_uverbs_poll_cq       cmd;
726         struct ib_uverbs_poll_cq_resp *resp;
727         struct ib_cq                  *cq;
728         struct ib_wc                  *wc;
729         int                            ret = 0;
730         int                            i;
731         int                            rsize;
732
733         if (copy_from_user(&cmd, buf, sizeof cmd))
734                 return -EFAULT;
735
736         wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
737         if (!wc)
738                 return -ENOMEM;
739
740         rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
741         resp = kmalloc(rsize, GFP_KERNEL);
742         if (!resp) {
743                 ret = -ENOMEM;
744                 goto out_wc;
745         }
746
747         mutex_lock(&ib_uverbs_idr_mutex);
748         cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
749         if (!cq || cq->uobject->context != file->ucontext) {
750                 ret = -EINVAL;
751                 goto out;
752         }
753
754         resp->count = ib_poll_cq(cq, cmd.ne, wc);
755
756         for (i = 0; i < resp->count; i++) {
757                 resp->wc[i].wr_id          = wc[i].wr_id;
758                 resp->wc[i].status         = wc[i].status;
759                 resp->wc[i].opcode         = wc[i].opcode;
760                 resp->wc[i].vendor_err     = wc[i].vendor_err;
761                 resp->wc[i].byte_len       = wc[i].byte_len;
762                 resp->wc[i].imm_data       = (__u32 __force) wc[i].imm_data;
763                 resp->wc[i].qp_num         = wc[i].qp_num;
764                 resp->wc[i].src_qp         = wc[i].src_qp;
765                 resp->wc[i].wc_flags       = wc[i].wc_flags;
766                 resp->wc[i].pkey_index     = wc[i].pkey_index;
767                 resp->wc[i].slid           = wc[i].slid;
768                 resp->wc[i].sl             = wc[i].sl;
769                 resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
770                 resp->wc[i].port_num       = wc[i].port_num;
771         }
772
773         if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
774                 ret = -EFAULT;
775
776 out:
777         mutex_unlock(&ib_uverbs_idr_mutex);
778         kfree(resp);
779
780 out_wc:
781         kfree(wc);
782         return ret ? ret : in_len;
783 }
784
785 ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
786                                 const char __user *buf, int in_len,
787                                 int out_len)
788 {
789         struct ib_uverbs_req_notify_cq cmd;
790         struct ib_cq                  *cq;
791         int                            ret = -EINVAL;
792
793         if (copy_from_user(&cmd, buf, sizeof cmd))
794                 return -EFAULT;
795
796         mutex_lock(&ib_uverbs_idr_mutex);
797         cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
798         if (cq && cq->uobject->context == file->ucontext) {
799                 ib_req_notify_cq(cq, cmd.solicited_only ?
800                                         IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
801                 ret = in_len;
802         }
803         mutex_unlock(&ib_uverbs_idr_mutex);
804
805         return ret;
806 }
807
808 ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
809                              const char __user *buf, int in_len,
810                              int out_len)
811 {
812         struct ib_uverbs_destroy_cq      cmd;
813         struct ib_uverbs_destroy_cq_resp resp;
814         struct ib_cq                    *cq;
815         struct ib_ucq_object            *uobj;
816         struct ib_uverbs_event_file     *ev_file;
817         u64                              user_handle;
818         int                              ret = -EINVAL;
819
820         if (copy_from_user(&cmd, buf, sizeof cmd))
821                 return -EFAULT;
822
823         memset(&resp, 0, sizeof resp);
824
825         mutex_lock(&ib_uverbs_idr_mutex);
826
827         cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
828         if (!cq || cq->uobject->context != file->ucontext)
829                 goto out;
830
831         user_handle = cq->uobject->user_handle;
832         uobj        = container_of(cq->uobject, struct ib_ucq_object, uobject);
833         ev_file     = cq->cq_context;
834
835         ret = ib_destroy_cq(cq);
836         if (ret)
837                 goto out;
838
839         idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
840
841         mutex_lock(&file->mutex);
842         list_del(&uobj->uobject.list);
843         mutex_unlock(&file->mutex);
844
845         ib_uverbs_release_ucq(file, ev_file, uobj);
846
847         resp.comp_events_reported  = uobj->comp_events_reported;
848         resp.async_events_reported = uobj->async_events_reported;
849
850         kfree(uobj);
851
852         if (copy_to_user((void __user *) (unsigned long) cmd.response,
853                          &resp, sizeof resp))
854                 ret = -EFAULT;
855
856 out:
857         mutex_unlock(&ib_uverbs_idr_mutex);
858
859         return ret ? ret : in_len;
860 }
861
862 ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
863                             const char __user *buf, int in_len,
864                             int out_len)
865 {
866         struct ib_uverbs_create_qp      cmd;
867         struct ib_uverbs_create_qp_resp resp;
868         struct ib_udata                 udata;
869         struct ib_uqp_object           *uobj;
870         struct ib_pd                   *pd;
871         struct ib_cq                   *scq, *rcq;
872         struct ib_srq                  *srq;
873         struct ib_qp                   *qp;
874         struct ib_qp_init_attr          attr;
875         int ret;
876
877         if (out_len < sizeof resp)
878                 return -ENOSPC;
879
880         if (copy_from_user(&cmd, buf, sizeof cmd))
881                 return -EFAULT;
882
883         INIT_UDATA(&udata, buf + sizeof cmd,
884                    (unsigned long) cmd.response + sizeof resp,
885                    in_len - sizeof cmd, out_len - sizeof resp);
886
887         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
888         if (!uobj)
889                 return -ENOMEM;
890
891         mutex_lock(&ib_uverbs_idr_mutex);
892
893         pd  = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
894         scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
895         rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
896         srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL;
897
898         if (!pd  || pd->uobject->context  != file->ucontext ||
899             !scq || scq->uobject->context != file->ucontext ||
900             !rcq || rcq->uobject->context != file->ucontext ||
901             (cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) {
902                 ret = -EINVAL;
903                 goto err_up;
904         }
905
906         attr.event_handler = ib_uverbs_qp_event_handler;
907         attr.qp_context    = file;
908         attr.send_cq       = scq;
909         attr.recv_cq       = rcq;
910         attr.srq           = srq;
911         attr.sq_sig_type   = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
912         attr.qp_type       = cmd.qp_type;
913
914         attr.cap.max_send_wr     = cmd.max_send_wr;
915         attr.cap.max_recv_wr     = cmd.max_recv_wr;
916         attr.cap.max_send_sge    = cmd.max_send_sge;
917         attr.cap.max_recv_sge    = cmd.max_recv_sge;
918         attr.cap.max_inline_data = cmd.max_inline_data;
919
920         uobj->uevent.uobject.user_handle = cmd.user_handle;
921         uobj->uevent.uobject.context     = file->ucontext;
922         uobj->uevent.events_reported     = 0;
923         INIT_LIST_HEAD(&uobj->uevent.event_list);
924         INIT_LIST_HEAD(&uobj->mcast_list);
925
926         qp = pd->device->create_qp(pd, &attr, &udata);
927         if (IS_ERR(qp)) {
928                 ret = PTR_ERR(qp);
929                 goto err_up;
930         }
931
932         qp->device        = pd->device;
933         qp->pd            = pd;
934         qp->send_cq       = attr.send_cq;
935         qp->recv_cq       = attr.recv_cq;
936         qp->srq           = attr.srq;
937         qp->uobject       = &uobj->uevent.uobject;
938         qp->event_handler = attr.event_handler;
939         qp->qp_context    = attr.qp_context;
940         qp->qp_type       = attr.qp_type;
941         atomic_inc(&pd->usecnt);
942         atomic_inc(&attr.send_cq->usecnt);
943         atomic_inc(&attr.recv_cq->usecnt);
944         if (attr.srq)
945                 atomic_inc(&attr.srq->usecnt);
946
947         memset(&resp, 0, sizeof resp);
948         resp.qpn = qp->qp_num;
949
950 retry:
951         if (!idr_pre_get(&ib_uverbs_qp_idr, GFP_KERNEL)) {
952                 ret = -ENOMEM;
953                 goto err_destroy;
954         }
955
956         ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->uevent.uobject.id);
957
958         if (ret == -EAGAIN)
959                 goto retry;
960         if (ret)
961                 goto err_destroy;
962
963         resp.qp_handle       = uobj->uevent.uobject.id;
964         resp.max_recv_sge    = attr.cap.max_recv_sge;
965         resp.max_send_sge    = attr.cap.max_send_sge;
966         resp.max_recv_wr     = attr.cap.max_recv_wr;
967         resp.max_send_wr     = attr.cap.max_send_wr;
968         resp.max_inline_data = attr.cap.max_inline_data;
969
970         if (copy_to_user((void __user *) (unsigned long) cmd.response,
971                          &resp, sizeof resp)) {
972                 ret = -EFAULT;
973                 goto err_idr;
974         }
975
976         mutex_lock(&file->mutex);
977         list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list);
978         mutex_unlock(&file->mutex);
979
980         mutex_unlock(&ib_uverbs_idr_mutex);
981
982         return in_len;
983
984 err_idr:
985         idr_remove(&ib_uverbs_qp_idr, uobj->uevent.uobject.id);
986
987 err_destroy:
988         ib_destroy_qp(qp);
989         atomic_dec(&pd->usecnt);
990         atomic_dec(&attr.send_cq->usecnt);
991         atomic_dec(&attr.recv_cq->usecnt);
992         if (attr.srq)
993                 atomic_dec(&attr.srq->usecnt);
994
995 err_up:
996         mutex_unlock(&ib_uverbs_idr_mutex);
997
998         kfree(uobj);
999         return ret;
1000 }
1001
1002 ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
1003                            const char __user *buf, int in_len,
1004                            int out_len)
1005 {
1006         struct ib_uverbs_query_qp      cmd;
1007         struct ib_uverbs_query_qp_resp resp;
1008         struct ib_qp                   *qp;
1009         struct ib_qp_attr              *attr;
1010         struct ib_qp_init_attr         *init_attr;
1011         int                            ret;
1012
1013         if (copy_from_user(&cmd, buf, sizeof cmd))
1014                 return -EFAULT;
1015
1016         attr      = kmalloc(sizeof *attr, GFP_KERNEL);
1017         init_attr = kmalloc(sizeof *init_attr, GFP_KERNEL);
1018         if (!attr || !init_attr) {
1019                 ret = -ENOMEM;
1020                 goto out;
1021         }
1022
1023         mutex_lock(&ib_uverbs_idr_mutex);
1024
1025         qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1026         if (qp && qp->uobject->context == file->ucontext)
1027                 ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr);
1028         else
1029                 ret = -EINVAL;
1030
1031         mutex_unlock(&ib_uverbs_idr_mutex);
1032
1033         if (ret)
1034                 goto out;
1035
1036         memset(&resp, 0, sizeof resp);
1037
1038         resp.qp_state               = attr->qp_state;
1039         resp.cur_qp_state           = attr->cur_qp_state;
1040         resp.path_mtu               = attr->path_mtu;
1041         resp.path_mig_state         = attr->path_mig_state;
1042         resp.qkey                   = attr->qkey;
1043         resp.rq_psn                 = attr->rq_psn;
1044         resp.sq_psn                 = attr->sq_psn;
1045         resp.dest_qp_num            = attr->dest_qp_num;
1046         resp.qp_access_flags        = attr->qp_access_flags;
1047         resp.pkey_index             = attr->pkey_index;
1048         resp.alt_pkey_index         = attr->alt_pkey_index;
1049         resp.en_sqd_async_notify    = attr->en_sqd_async_notify;
1050         resp.max_rd_atomic          = attr->max_rd_atomic;
1051         resp.max_dest_rd_atomic     = attr->max_dest_rd_atomic;
1052         resp.min_rnr_timer          = attr->min_rnr_timer;
1053         resp.port_num               = attr->port_num;
1054         resp.timeout                = attr->timeout;
1055         resp.retry_cnt              = attr->retry_cnt;
1056         resp.rnr_retry              = attr->rnr_retry;
1057         resp.alt_port_num           = attr->alt_port_num;
1058         resp.alt_timeout            = attr->alt_timeout;
1059
1060         memcpy(resp.dest.dgid, attr->ah_attr.grh.dgid.raw, 16);
1061         resp.dest.flow_label        = attr->ah_attr.grh.flow_label;
1062         resp.dest.sgid_index        = attr->ah_attr.grh.sgid_index;
1063         resp.dest.hop_limit         = attr->ah_attr.grh.hop_limit;
1064         resp.dest.traffic_class     = attr->ah_attr.grh.traffic_class;
1065         resp.dest.dlid              = attr->ah_attr.dlid;
1066         resp.dest.sl                = attr->ah_attr.sl;
1067         resp.dest.src_path_bits     = attr->ah_attr.src_path_bits;
1068         resp.dest.static_rate       = attr->ah_attr.static_rate;
1069         resp.dest.is_global         = !!(attr->ah_attr.ah_flags & IB_AH_GRH);
1070         resp.dest.port_num          = attr->ah_attr.port_num;
1071
1072         memcpy(resp.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16);
1073         resp.alt_dest.flow_label    = attr->alt_ah_attr.grh.flow_label;
1074         resp.alt_dest.sgid_index    = attr->alt_ah_attr.grh.sgid_index;
1075         resp.alt_dest.hop_limit     = attr->alt_ah_attr.grh.hop_limit;
1076         resp.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class;
1077         resp.alt_dest.dlid          = attr->alt_ah_attr.dlid;
1078         resp.alt_dest.sl            = attr->alt_ah_attr.sl;
1079         resp.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits;
1080         resp.alt_dest.static_rate   = attr->alt_ah_attr.static_rate;
1081         resp.alt_dest.is_global     = !!(attr->alt_ah_attr.ah_flags & IB_AH_GRH);
1082         resp.alt_dest.port_num      = attr->alt_ah_attr.port_num;
1083
1084         resp.max_send_wr            = init_attr->cap.max_send_wr;
1085         resp.max_recv_wr            = init_attr->cap.max_recv_wr;
1086         resp.max_send_sge           = init_attr->cap.max_send_sge;
1087         resp.max_recv_sge           = init_attr->cap.max_recv_sge;
1088         resp.max_inline_data        = init_attr->cap.max_inline_data;
1089         resp.sq_sig_all             = init_attr->sq_sig_type == IB_SIGNAL_ALL_WR;
1090
1091         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1092                          &resp, sizeof resp))
1093                 ret = -EFAULT;
1094
1095 out:
1096         kfree(attr);
1097         kfree(init_attr);
1098
1099         return ret ? ret : in_len;
1100 }
1101
1102 ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1103                             const char __user *buf, int in_len,
1104                             int out_len)
1105 {
1106         struct ib_uverbs_modify_qp cmd;
1107         struct ib_qp              *qp;
1108         struct ib_qp_attr         *attr;
1109         int                        ret;
1110
1111         if (copy_from_user(&cmd, buf, sizeof cmd))
1112                 return -EFAULT;
1113
1114         attr = kmalloc(sizeof *attr, GFP_KERNEL);
1115         if (!attr)
1116                 return -ENOMEM;
1117
1118         mutex_lock(&ib_uverbs_idr_mutex);
1119
1120         qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1121         if (!qp || qp->uobject->context != file->ucontext) {
1122                 ret = -EINVAL;
1123                 goto out;
1124         }
1125
1126         attr->qp_state            = cmd.qp_state;
1127         attr->cur_qp_state        = cmd.cur_qp_state;
1128         attr->path_mtu            = cmd.path_mtu;
1129         attr->path_mig_state      = cmd.path_mig_state;
1130         attr->qkey                = cmd.qkey;
1131         attr->rq_psn              = cmd.rq_psn;
1132         attr->sq_psn              = cmd.sq_psn;
1133         attr->dest_qp_num         = cmd.dest_qp_num;
1134         attr->qp_access_flags     = cmd.qp_access_flags;
1135         attr->pkey_index          = cmd.pkey_index;
1136         attr->alt_pkey_index      = cmd.alt_pkey_index;
1137         attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
1138         attr->max_rd_atomic       = cmd.max_rd_atomic;
1139         attr->max_dest_rd_atomic  = cmd.max_dest_rd_atomic;
1140         attr->min_rnr_timer       = cmd.min_rnr_timer;
1141         attr->port_num            = cmd.port_num;
1142         attr->timeout             = cmd.timeout;
1143         attr->retry_cnt           = cmd.retry_cnt;
1144         attr->rnr_retry           = cmd.rnr_retry;
1145         attr->alt_port_num        = cmd.alt_port_num;
1146         attr->alt_timeout         = cmd.alt_timeout;
1147
1148         memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
1149         attr->ah_attr.grh.flow_label        = cmd.dest.flow_label;
1150         attr->ah_attr.grh.sgid_index        = cmd.dest.sgid_index;
1151         attr->ah_attr.grh.hop_limit         = cmd.dest.hop_limit;
1152         attr->ah_attr.grh.traffic_class     = cmd.dest.traffic_class;
1153         attr->ah_attr.dlid                  = cmd.dest.dlid;
1154         attr->ah_attr.sl                    = cmd.dest.sl;
1155         attr->ah_attr.src_path_bits         = cmd.dest.src_path_bits;
1156         attr->ah_attr.static_rate           = cmd.dest.static_rate;
1157         attr->ah_attr.ah_flags              = cmd.dest.is_global ? IB_AH_GRH : 0;
1158         attr->ah_attr.port_num              = cmd.dest.port_num;
1159
1160         memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
1161         attr->alt_ah_attr.grh.flow_label    = cmd.alt_dest.flow_label;
1162         attr->alt_ah_attr.grh.sgid_index    = cmd.alt_dest.sgid_index;
1163         attr->alt_ah_attr.grh.hop_limit     = cmd.alt_dest.hop_limit;
1164         attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
1165         attr->alt_ah_attr.dlid              = cmd.alt_dest.dlid;
1166         attr->alt_ah_attr.sl                = cmd.alt_dest.sl;
1167         attr->alt_ah_attr.src_path_bits     = cmd.alt_dest.src_path_bits;
1168         attr->alt_ah_attr.static_rate       = cmd.alt_dest.static_rate;
1169         attr->alt_ah_attr.ah_flags          = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
1170         attr->alt_ah_attr.port_num          = cmd.alt_dest.port_num;
1171
1172         ret = ib_modify_qp(qp, attr, cmd.attr_mask);
1173         if (ret)
1174                 goto out;
1175
1176         ret = in_len;
1177
1178 out:
1179         mutex_unlock(&ib_uverbs_idr_mutex);
1180         kfree(attr);
1181
1182         return ret;
1183 }
1184
1185 ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1186                              const char __user *buf, int in_len,
1187                              int out_len)
1188 {
1189         struct ib_uverbs_destroy_qp      cmd;
1190         struct ib_uverbs_destroy_qp_resp resp;
1191         struct ib_qp                    *qp;
1192         struct ib_uqp_object            *uobj;
1193         int                              ret = -EINVAL;
1194
1195         if (copy_from_user(&cmd, buf, sizeof cmd))
1196                 return -EFAULT;
1197
1198         memset(&resp, 0, sizeof resp);
1199
1200         mutex_lock(&ib_uverbs_idr_mutex);
1201
1202         qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1203         if (!qp || qp->uobject->context != file->ucontext)
1204                 goto out;
1205
1206         uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
1207
1208         if (!list_empty(&uobj->mcast_list)) {
1209                 ret = -EBUSY;
1210                 goto out;
1211         }
1212
1213         ret = ib_destroy_qp(qp);
1214         if (ret)
1215                 goto out;
1216
1217         idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
1218
1219         mutex_lock(&file->mutex);
1220         list_del(&uobj->uevent.uobject.list);
1221         mutex_unlock(&file->mutex);
1222
1223         ib_uverbs_release_uevent(file, &uobj->uevent);
1224
1225         resp.events_reported = uobj->uevent.events_reported;
1226
1227         kfree(uobj);
1228
1229         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1230                          &resp, sizeof resp))
1231                 ret = -EFAULT;
1232
1233 out:
1234         mutex_unlock(&ib_uverbs_idr_mutex);
1235
1236         return ret ? ret : in_len;
1237 }
1238
1239 ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1240                             const char __user *buf, int in_len,
1241                             int out_len)
1242 {
1243         struct ib_uverbs_post_send      cmd;
1244         struct ib_uverbs_post_send_resp resp;
1245         struct ib_uverbs_send_wr       *user_wr;
1246         struct ib_send_wr              *wr = NULL, *last, *next, *bad_wr;
1247         struct ib_qp                   *qp;
1248         int                             i, sg_ind;
1249         ssize_t                         ret = -EINVAL;
1250
1251         if (copy_from_user(&cmd, buf, sizeof cmd))
1252                 return -EFAULT;
1253
1254         if (in_len < sizeof cmd + cmd.wqe_size * cmd.wr_count +
1255             cmd.sge_count * sizeof (struct ib_uverbs_sge))
1256                 return -EINVAL;
1257
1258         if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr))
1259                 return -EINVAL;
1260
1261         user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL);
1262         if (!user_wr)
1263                 return -ENOMEM;
1264
1265         mutex_lock(&ib_uverbs_idr_mutex);
1266
1267         qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1268         if (!qp || qp->uobject->context != file->ucontext)
1269                 goto out;
1270
1271         sg_ind = 0;
1272         last = NULL;
1273         for (i = 0; i < cmd.wr_count; ++i) {
1274                 if (copy_from_user(user_wr,
1275                                    buf + sizeof cmd + i * cmd.wqe_size,
1276                                    cmd.wqe_size)) {
1277                         ret = -EFAULT;
1278                         goto out;
1279                 }
1280
1281                 if (user_wr->num_sge + sg_ind > cmd.sge_count) {
1282                         ret = -EINVAL;
1283                         goto out;
1284                 }
1285
1286                 next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
1287                                user_wr->num_sge * sizeof (struct ib_sge),
1288                                GFP_KERNEL);
1289                 if (!next) {
1290                         ret = -ENOMEM;
1291                         goto out;
1292                 }
1293
1294                 if (!last)
1295                         wr = next;
1296                 else
1297                         last->next = next;
1298                 last = next;
1299
1300                 next->next       = NULL;
1301                 next->wr_id      = user_wr->wr_id;
1302                 next->num_sge    = user_wr->num_sge;
1303                 next->opcode     = user_wr->opcode;
1304                 next->send_flags = user_wr->send_flags;
1305                 next->imm_data   = (__be32 __force) user_wr->imm_data;
1306
1307                 if (qp->qp_type == IB_QPT_UD) {
1308                         next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr,
1309                                                   user_wr->wr.ud.ah);
1310                         if (!next->wr.ud.ah) {
1311                                 ret = -EINVAL;
1312                                 goto out;
1313                         }
1314                         next->wr.ud.remote_qpn  = user_wr->wr.ud.remote_qpn;
1315                         next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey;
1316                 } else {
1317                         switch (next->opcode) {
1318                         case IB_WR_RDMA_WRITE:
1319                         case IB_WR_RDMA_WRITE_WITH_IMM:
1320                         case IB_WR_RDMA_READ:
1321                                 next->wr.rdma.remote_addr =
1322                                         user_wr->wr.rdma.remote_addr;
1323                                 next->wr.rdma.rkey        =
1324                                         user_wr->wr.rdma.rkey;
1325                                 break;
1326                         case IB_WR_ATOMIC_CMP_AND_SWP:
1327                         case IB_WR_ATOMIC_FETCH_AND_ADD:
1328                                 next->wr.atomic.remote_addr =
1329                                         user_wr->wr.atomic.remote_addr;
1330                                 next->wr.atomic.compare_add =
1331                                         user_wr->wr.atomic.compare_add;
1332                                 next->wr.atomic.swap = user_wr->wr.atomic.swap;
1333                                 next->wr.atomic.rkey = user_wr->wr.atomic.rkey;
1334                                 break;
1335                         default:
1336                                 break;
1337                         }
1338                 }
1339
1340                 if (next->num_sge) {
1341                         next->sg_list = (void *) next +
1342                                 ALIGN(sizeof *next, sizeof (struct ib_sge));
1343                         if (copy_from_user(next->sg_list,
1344                                            buf + sizeof cmd +
1345                                            cmd.wr_count * cmd.wqe_size +
1346                                            sg_ind * sizeof (struct ib_sge),
1347                                            next->num_sge * sizeof (struct ib_sge))) {
1348                                 ret = -EFAULT;
1349                                 goto out;
1350                         }
1351                         sg_ind += next->num_sge;
1352                 } else
1353                         next->sg_list = NULL;
1354         }
1355
1356         resp.bad_wr = 0;
1357         ret = qp->device->post_send(qp, wr, &bad_wr);
1358         if (ret)
1359                 for (next = wr; next; next = next->next) {
1360                         ++resp.bad_wr;
1361                         if (next == bad_wr)
1362                                 break;
1363                 }
1364
1365         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1366                          &resp, sizeof resp))
1367                 ret = -EFAULT;
1368
1369 out:
1370         mutex_unlock(&ib_uverbs_idr_mutex);
1371
1372         while (wr) {
1373                 next = wr->next;
1374                 kfree(wr);
1375                 wr = next;
1376         }
1377
1378         kfree(user_wr);
1379
1380         return ret ? ret : in_len;
1381 }
1382
1383 static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf,
1384                                                     int in_len,
1385                                                     u32 wr_count,
1386                                                     u32 sge_count,
1387                                                     u32 wqe_size)
1388 {
1389         struct ib_uverbs_recv_wr *user_wr;
1390         struct ib_recv_wr        *wr = NULL, *last, *next;
1391         int                       sg_ind;
1392         int                       i;
1393         int                       ret;
1394
1395         if (in_len < wqe_size * wr_count +
1396             sge_count * sizeof (struct ib_uverbs_sge))
1397                 return ERR_PTR(-EINVAL);
1398
1399         if (wqe_size < sizeof (struct ib_uverbs_recv_wr))
1400                 return ERR_PTR(-EINVAL);
1401
1402         user_wr = kmalloc(wqe_size, GFP_KERNEL);
1403         if (!user_wr)
1404                 return ERR_PTR(-ENOMEM);
1405
1406         sg_ind = 0;
1407         last = NULL;
1408         for (i = 0; i < wr_count; ++i) {
1409                 if (copy_from_user(user_wr, buf + i * wqe_size,
1410                                    wqe_size)) {
1411                         ret = -EFAULT;
1412                         goto err;
1413                 }
1414
1415                 if (user_wr->num_sge + sg_ind > sge_count) {
1416                         ret = -EINVAL;
1417                         goto err;
1418                 }
1419
1420                 next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
1421                                user_wr->num_sge * sizeof (struct ib_sge),
1422                                GFP_KERNEL);
1423                 if (!next) {
1424                         ret = -ENOMEM;
1425                         goto err;
1426                 }
1427
1428                 if (!last)
1429                         wr = next;
1430                 else
1431                         last->next = next;
1432                 last = next;
1433
1434                 next->next       = NULL;
1435                 next->wr_id      = user_wr->wr_id;
1436                 next->num_sge    = user_wr->num_sge;
1437
1438                 if (next->num_sge) {
1439                         next->sg_list = (void *) next +
1440                                 ALIGN(sizeof *next, sizeof (struct ib_sge));
1441                         if (copy_from_user(next->sg_list,
1442                                            buf + wr_count * wqe_size +
1443                                            sg_ind * sizeof (struct ib_sge),
1444                                            next->num_sge * sizeof (struct ib_sge))) {
1445                                 ret = -EFAULT;
1446                                 goto err;
1447                         }
1448                         sg_ind += next->num_sge;
1449                 } else
1450                         next->sg_list = NULL;
1451         }
1452
1453         kfree(user_wr);
1454         return wr;
1455
1456 err:
1457         kfree(user_wr);
1458
1459         while (wr) {
1460                 next = wr->next;
1461                 kfree(wr);
1462                 wr = next;
1463         }
1464
1465         return ERR_PTR(ret);
1466 }
1467
1468 ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
1469                             const char __user *buf, int in_len,
1470                             int out_len)
1471 {
1472         struct ib_uverbs_post_recv      cmd;
1473         struct ib_uverbs_post_recv_resp resp;
1474         struct ib_recv_wr              *wr, *next, *bad_wr;
1475         struct ib_qp                   *qp;
1476         ssize_t                         ret = -EINVAL;
1477
1478         if (copy_from_user(&cmd, buf, sizeof cmd))
1479                 return -EFAULT;
1480
1481         wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
1482                                        in_len - sizeof cmd, cmd.wr_count,
1483                                        cmd.sge_count, cmd.wqe_size);
1484         if (IS_ERR(wr))
1485                 return PTR_ERR(wr);
1486
1487         mutex_lock(&ib_uverbs_idr_mutex);
1488
1489         qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1490         if (!qp || qp->uobject->context != file->ucontext)
1491                 goto out;
1492
1493         resp.bad_wr = 0;
1494         ret = qp->device->post_recv(qp, wr, &bad_wr);
1495         if (ret)
1496                 for (next = wr; next; next = next->next) {
1497                         ++resp.bad_wr;
1498                         if (next == bad_wr)
1499                                 break;
1500                 }
1501
1502
1503         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1504                          &resp, sizeof resp))
1505                 ret = -EFAULT;
1506
1507 out:
1508         mutex_unlock(&ib_uverbs_idr_mutex);
1509
1510         while (wr) {
1511                 next = wr->next;
1512                 kfree(wr);
1513                 wr = next;
1514         }
1515
1516         return ret ? ret : in_len;
1517 }
1518
1519 ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
1520                                 const char __user *buf, int in_len,
1521                                 int out_len)
1522 {
1523         struct ib_uverbs_post_srq_recv      cmd;
1524         struct ib_uverbs_post_srq_recv_resp resp;
1525         struct ib_recv_wr                  *wr, *next, *bad_wr;
1526         struct ib_srq                      *srq;
1527         ssize_t                             ret = -EINVAL;
1528
1529         if (copy_from_user(&cmd, buf, sizeof cmd))
1530                 return -EFAULT;
1531
1532         wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
1533                                        in_len - sizeof cmd, cmd.wr_count,
1534                                        cmd.sge_count, cmd.wqe_size);
1535         if (IS_ERR(wr))
1536                 return PTR_ERR(wr);
1537
1538         mutex_lock(&ib_uverbs_idr_mutex);
1539
1540         srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1541         if (!srq || srq->uobject->context != file->ucontext)
1542                 goto out;
1543
1544         resp.bad_wr = 0;
1545         ret = srq->device->post_srq_recv(srq, wr, &bad_wr);
1546         if (ret)
1547                 for (next = wr; next; next = next->next) {
1548                         ++resp.bad_wr;
1549                         if (next == bad_wr)
1550                                 break;
1551                 }
1552
1553
1554         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1555                          &resp, sizeof resp))
1556                 ret = -EFAULT;
1557
1558 out:
1559         mutex_unlock(&ib_uverbs_idr_mutex);
1560
1561         while (wr) {
1562                 next = wr->next;
1563                 kfree(wr);
1564                 wr = next;
1565         }
1566
1567         return ret ? ret : in_len;
1568 }
1569
1570 ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
1571                             const char __user *buf, int in_len,
1572                             int out_len)
1573 {
1574         struct ib_uverbs_create_ah       cmd;
1575         struct ib_uverbs_create_ah_resp  resp;
1576         struct ib_uobject               *uobj;
1577         struct ib_pd                    *pd;
1578         struct ib_ah                    *ah;
1579         struct ib_ah_attr               attr;
1580         int ret;
1581
1582         if (out_len < sizeof resp)
1583                 return -ENOSPC;
1584
1585         if (copy_from_user(&cmd, buf, sizeof cmd))
1586                 return -EFAULT;
1587
1588         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
1589         if (!uobj)
1590                 return -ENOMEM;
1591
1592         mutex_lock(&ib_uverbs_idr_mutex);
1593
1594         pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
1595         if (!pd || pd->uobject->context != file->ucontext) {
1596                 ret = -EINVAL;
1597                 goto err_up;
1598         }
1599
1600         uobj->user_handle = cmd.user_handle;
1601         uobj->context     = file->ucontext;
1602
1603         attr.dlid              = cmd.attr.dlid;
1604         attr.sl                = cmd.attr.sl;
1605         attr.src_path_bits     = cmd.attr.src_path_bits;
1606         attr.static_rate       = cmd.attr.static_rate;
1607         attr.ah_flags          = cmd.attr.is_global ? IB_AH_GRH : 0;
1608         attr.port_num          = cmd.attr.port_num;
1609         attr.grh.flow_label    = cmd.attr.grh.flow_label;
1610         attr.grh.sgid_index    = cmd.attr.grh.sgid_index;
1611         attr.grh.hop_limit     = cmd.attr.grh.hop_limit;
1612         attr.grh.traffic_class = cmd.attr.grh.traffic_class;
1613         memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16);
1614
1615         ah = ib_create_ah(pd, &attr);
1616         if (IS_ERR(ah)) {
1617                 ret = PTR_ERR(ah);
1618                 goto err_up;
1619         }
1620
1621         ah->uobject = uobj;
1622
1623 retry:
1624         if (!idr_pre_get(&ib_uverbs_ah_idr, GFP_KERNEL)) {
1625                 ret = -ENOMEM;
1626                 goto err_destroy;
1627         }
1628
1629         ret = idr_get_new(&ib_uverbs_ah_idr, ah, &uobj->id);
1630
1631         if (ret == -EAGAIN)
1632                 goto retry;
1633         if (ret)
1634                 goto err_destroy;
1635
1636         resp.ah_handle = uobj->id;
1637
1638         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1639                          &resp, sizeof resp)) {
1640                 ret = -EFAULT;
1641                 goto err_idr;
1642         }
1643
1644         mutex_lock(&file->mutex);
1645         list_add_tail(&uobj->list, &file->ucontext->ah_list);
1646         mutex_unlock(&file->mutex);
1647
1648         mutex_unlock(&ib_uverbs_idr_mutex);
1649
1650         return in_len;
1651
1652 err_idr:
1653         idr_remove(&ib_uverbs_ah_idr, uobj->id);
1654
1655 err_destroy:
1656         ib_destroy_ah(ah);
1657
1658 err_up:
1659         mutex_unlock(&ib_uverbs_idr_mutex);
1660
1661         kfree(uobj);
1662         return ret;
1663 }
1664
1665 ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
1666                              const char __user *buf, int in_len, int out_len)
1667 {
1668         struct ib_uverbs_destroy_ah cmd;
1669         struct ib_ah               *ah;
1670         struct ib_uobject          *uobj;
1671         int                         ret = -EINVAL;
1672
1673         if (copy_from_user(&cmd, buf, sizeof cmd))
1674                 return -EFAULT;
1675
1676         mutex_lock(&ib_uverbs_idr_mutex);
1677
1678         ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle);
1679         if (!ah || ah->uobject->context != file->ucontext)
1680                 goto out;
1681
1682         uobj = ah->uobject;
1683
1684         ret = ib_destroy_ah(ah);
1685         if (ret)
1686                 goto out;
1687
1688         idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle);
1689
1690         mutex_lock(&file->mutex);
1691         list_del(&uobj->list);
1692         mutex_unlock(&file->mutex);
1693
1694         kfree(uobj);
1695
1696 out:
1697         mutex_unlock(&ib_uverbs_idr_mutex);
1698
1699         return ret ? ret : in_len;
1700 }
1701
1702 ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
1703                                const char __user *buf, int in_len,
1704                                int out_len)
1705 {
1706         struct ib_uverbs_attach_mcast cmd;
1707         struct ib_qp                 *qp;
1708         struct ib_uqp_object         *uobj;
1709         struct ib_uverbs_mcast_entry *mcast;
1710         int                           ret = -EINVAL;
1711
1712         if (copy_from_user(&cmd, buf, sizeof cmd))
1713                 return -EFAULT;
1714
1715         mutex_lock(&ib_uverbs_idr_mutex);
1716
1717         qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1718         if (!qp || qp->uobject->context != file->ucontext)
1719                 goto out;
1720
1721         uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
1722
1723         list_for_each_entry(mcast, &uobj->mcast_list, list)
1724                 if (cmd.mlid == mcast->lid &&
1725                     !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
1726                         ret = 0;
1727                         goto out;
1728                 }
1729
1730         mcast = kmalloc(sizeof *mcast, GFP_KERNEL);
1731         if (!mcast) {
1732                 ret = -ENOMEM;
1733                 goto out;
1734         }
1735
1736         mcast->lid = cmd.mlid;
1737         memcpy(mcast->gid.raw, cmd.gid, sizeof mcast->gid.raw);
1738
1739         ret = ib_attach_mcast(qp, &mcast->gid, cmd.mlid);
1740         if (!ret) {
1741                 uobj = container_of(qp->uobject, struct ib_uqp_object,
1742                                     uevent.uobject);
1743                 list_add_tail(&mcast->list, &uobj->mcast_list);
1744         } else
1745                 kfree(mcast);
1746
1747 out:
1748         mutex_unlock(&ib_uverbs_idr_mutex);
1749
1750         return ret ? ret : in_len;
1751 }
1752
1753 ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1754                                const char __user *buf, int in_len,
1755                                int out_len)
1756 {
1757         struct ib_uverbs_detach_mcast cmd;
1758         struct ib_uqp_object         *uobj;
1759         struct ib_qp                 *qp;
1760         struct ib_uverbs_mcast_entry *mcast;
1761         int                           ret = -EINVAL;
1762
1763         if (copy_from_user(&cmd, buf, sizeof cmd))
1764                 return -EFAULT;
1765
1766         mutex_lock(&ib_uverbs_idr_mutex);
1767
1768         qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1769         if (!qp || qp->uobject->context != file->ucontext)
1770                 goto out;
1771
1772         ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
1773         if (ret)
1774                 goto out;
1775
1776         uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
1777
1778         list_for_each_entry(mcast, &uobj->mcast_list, list)
1779                 if (cmd.mlid == mcast->lid &&
1780                     !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
1781                         list_del(&mcast->list);
1782                         kfree(mcast);
1783                         break;
1784                 }
1785
1786 out:
1787         mutex_unlock(&ib_uverbs_idr_mutex);
1788
1789         return ret ? ret : in_len;
1790 }
1791
1792 ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
1793                              const char __user *buf, int in_len,
1794                              int out_len)
1795 {
1796         struct ib_uverbs_create_srq      cmd;
1797         struct ib_uverbs_create_srq_resp resp;
1798         struct ib_udata                  udata;
1799         struct ib_uevent_object         *uobj;
1800         struct ib_pd                    *pd;
1801         struct ib_srq                   *srq;
1802         struct ib_srq_init_attr          attr;
1803         int ret;
1804
1805         if (out_len < sizeof resp)
1806                 return -ENOSPC;
1807
1808         if (copy_from_user(&cmd, buf, sizeof cmd))
1809                 return -EFAULT;
1810
1811         INIT_UDATA(&udata, buf + sizeof cmd,
1812                    (unsigned long) cmd.response + sizeof resp,
1813                    in_len - sizeof cmd, out_len - sizeof resp);
1814
1815         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
1816         if (!uobj)
1817                 return -ENOMEM;
1818
1819         mutex_lock(&ib_uverbs_idr_mutex);
1820
1821         pd  = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
1822
1823         if (!pd || pd->uobject->context != file->ucontext) {
1824                 ret = -EINVAL;
1825                 goto err_up;
1826         }
1827
1828         attr.event_handler  = ib_uverbs_srq_event_handler;
1829         attr.srq_context    = file;
1830         attr.attr.max_wr    = cmd.max_wr;
1831         attr.attr.max_sge   = cmd.max_sge;
1832         attr.attr.srq_limit = cmd.srq_limit;
1833
1834         uobj->uobject.user_handle = cmd.user_handle;
1835         uobj->uobject.context     = file->ucontext;
1836         uobj->events_reported     = 0;
1837         INIT_LIST_HEAD(&uobj->event_list);
1838
1839         srq = pd->device->create_srq(pd, &attr, &udata);
1840         if (IS_ERR(srq)) {
1841                 ret = PTR_ERR(srq);
1842                 goto err_up;
1843         }
1844
1845         srq->device        = pd->device;
1846         srq->pd            = pd;
1847         srq->uobject       = &uobj->uobject;
1848         srq->event_handler = attr.event_handler;
1849         srq->srq_context   = attr.srq_context;
1850         atomic_inc(&pd->usecnt);
1851         atomic_set(&srq->usecnt, 0);
1852
1853         memset(&resp, 0, sizeof resp);
1854
1855 retry:
1856         if (!idr_pre_get(&ib_uverbs_srq_idr, GFP_KERNEL)) {
1857                 ret = -ENOMEM;
1858                 goto err_destroy;
1859         }
1860
1861         ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->uobject.id);
1862
1863         if (ret == -EAGAIN)
1864                 goto retry;
1865         if (ret)
1866                 goto err_destroy;
1867
1868         resp.srq_handle = uobj->uobject.id;
1869         resp.max_wr     = attr.attr.max_wr;
1870         resp.max_sge    = attr.attr.max_sge;
1871
1872         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1873                          &resp, sizeof resp)) {
1874                 ret = -EFAULT;
1875                 goto err_idr;
1876         }
1877
1878         mutex_lock(&file->mutex);
1879         list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
1880         mutex_unlock(&file->mutex);
1881
1882         mutex_unlock(&ib_uverbs_idr_mutex);
1883
1884         return in_len;
1885
1886 err_idr:
1887         idr_remove(&ib_uverbs_srq_idr, uobj->uobject.id);
1888
1889 err_destroy:
1890         ib_destroy_srq(srq);
1891         atomic_dec(&pd->usecnt);
1892
1893 err_up:
1894         mutex_unlock(&ib_uverbs_idr_mutex);
1895
1896         kfree(uobj);
1897         return ret;
1898 }
1899
1900 ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1901                              const char __user *buf, int in_len,
1902                              int out_len)
1903 {
1904         struct ib_uverbs_modify_srq cmd;
1905         struct ib_srq              *srq;
1906         struct ib_srq_attr          attr;
1907         int                         ret;
1908
1909         if (copy_from_user(&cmd, buf, sizeof cmd))
1910                 return -EFAULT;
1911
1912         mutex_lock(&ib_uverbs_idr_mutex);
1913
1914         srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1915         if (!srq || srq->uobject->context != file->ucontext) {
1916                 ret = -EINVAL;
1917                 goto out;
1918         }
1919
1920         attr.max_wr    = cmd.max_wr;
1921         attr.srq_limit = cmd.srq_limit;
1922
1923         ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
1924
1925 out:
1926         mutex_unlock(&ib_uverbs_idr_mutex);
1927
1928         return ret ? ret : in_len;
1929 }
1930
1931 ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file,
1932                             const char __user *buf,
1933                             int in_len, int out_len)
1934 {
1935         struct ib_uverbs_query_srq      cmd;
1936         struct ib_uverbs_query_srq_resp resp;
1937         struct ib_srq_attr              attr;
1938         struct ib_srq                   *srq;
1939         int                             ret;
1940
1941         if (out_len < sizeof resp)
1942                 return -ENOSPC;
1943
1944         if (copy_from_user(&cmd, buf, sizeof cmd))
1945                 return -EFAULT;
1946
1947         mutex_lock(&ib_uverbs_idr_mutex);
1948
1949         srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1950         if (srq && srq->uobject->context == file->ucontext)
1951                 ret = ib_query_srq(srq, &attr);
1952         else
1953                 ret = -EINVAL;
1954
1955         mutex_unlock(&ib_uverbs_idr_mutex);
1956
1957         if (ret)
1958                 goto out;
1959
1960         memset(&resp, 0, sizeof resp);
1961
1962         resp.max_wr    = attr.max_wr;
1963         resp.max_sge   = attr.max_sge;
1964         resp.srq_limit = attr.srq_limit;
1965
1966         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1967                          &resp, sizeof resp))
1968                 ret = -EFAULT;
1969
1970 out:
1971         return ret ? ret : in_len;
1972 }
1973
1974 ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
1975                               const char __user *buf, int in_len,
1976                               int out_len)
1977 {
1978         struct ib_uverbs_destroy_srq      cmd;
1979         struct ib_uverbs_destroy_srq_resp resp;
1980         struct ib_srq                    *srq;
1981         struct ib_uevent_object          *uobj;
1982         int                               ret = -EINVAL;
1983
1984         if (copy_from_user(&cmd, buf, sizeof cmd))
1985                 return -EFAULT;
1986
1987         mutex_lock(&ib_uverbs_idr_mutex);
1988
1989         memset(&resp, 0, sizeof resp);
1990
1991         srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1992         if (!srq || srq->uobject->context != file->ucontext)
1993                 goto out;
1994
1995         uobj = container_of(srq->uobject, struct ib_uevent_object, uobject);
1996
1997         ret = ib_destroy_srq(srq);
1998         if (ret)
1999                 goto out;
2000
2001         idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
2002
2003         mutex_lock(&file->mutex);
2004         list_del(&uobj->uobject.list);
2005         mutex_unlock(&file->mutex);
2006
2007         ib_uverbs_release_uevent(file, uobj);
2008
2009         resp.events_reported = uobj->events_reported;
2010
2011         kfree(uobj);
2012
2013         if (copy_to_user((void __user *) (unsigned long) cmd.response,
2014                          &resp, sizeof resp))
2015                 ret = -EFAULT;
2016
2017 out:
2018         mutex_unlock(&ib_uverbs_idr_mutex);
2019
2020         return ret ? ret : in_len;
2021 }