strace: Remove the ability to write to Qstrace
[akaros.git] / kern / drivers / net / udrvr / uverbs_cmd.c
1 /*
2  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005, 2006, 2007 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
36 #if 0   /* AKAROS */
37 #include <linux/file.h>
38 #include <linux/fs.h>
39 #include <linux/slab.h>
40 #include <linux/sched.h>
41
42 #include <asm/uaccess.h>
43
44 #include "uverbs.h"
45 #include "core_priv.h"
46 #else   /* AKAROS */
47 #include "uverbs.h"
48
49 static void release_uobj(struct kref *kref);
50 #define kref_init(p)    kref_init(p, release_uobj, 1)
51 #define kref_put(p, f)  kref_put(p)
52 #define kref_get(p)     kref_get(p, 1)
53
54 #define get_task_pid(a, b)      NULL
55 #define put_pid(p)
56
57 #define ib_resolve_eth_l2_attrs(qp, attr, attrp)        0
58 #define capable(c)                                      1
59
60 /*
61  * Someone "ported" include/linux/rdma/ib_verbs.h and killed the "mutex"
62  * field in "struct ib_uobject". Need to add that back in. In the meantime,
63  * hack around this ....
64  */
65 #define init_rwsem(p)
66 #define up_read(p)
67 #define up_write(p)
68 #define down_read(p)
69 #define down_write(p)
70 #define down_read_nested(p, d)
71
72 # define lockdep_set_class_and_name(lock, key, name) \
73                 do { (void)(key); (void)(name); } while (0)
74
75 #endif  /* AKAROS */
76
77 struct uverbs_lock_class {
78         struct lock_class_key   key;
79         char                    name[16];
80 };
81
82 static struct uverbs_lock_class pd_lock_class   = { .name = "PD-uobj" };
83 static struct uverbs_lock_class mr_lock_class   = { .name = "MR-uobj" };
84 static struct uverbs_lock_class mw_lock_class   = { .name = "MW-uobj" };
85 static struct uverbs_lock_class cq_lock_class   = { .name = "CQ-uobj" };
86 static struct uverbs_lock_class qp_lock_class   = { .name = "QP-uobj" };
87 static struct uverbs_lock_class ah_lock_class   = { .name = "AH-uobj" };
88 static struct uverbs_lock_class srq_lock_class  = { .name = "SRQ-uobj" };
89 static struct uverbs_lock_class xrcd_lock_class = { .name = "XRCD-uobj" };
90 static struct uverbs_lock_class rule_lock_class = { .name = "RULE-uobj" };
91
92 /*
93  * The ib_uobject locking scheme is as follows:
94  *
95  * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it
96  *   needs to be held during all idr operations.  When an object is
97  *   looked up, a reference must be taken on the object's kref before
98  *   dropping this lock.
99  *
100  * - Each object also has an rwsem.  This rwsem must be held for
101  *   reading while an operation that uses the object is performed.
102  *   For example, while registering an MR, the associated PD's
103  *   uobject.mutex must be held for reading.  The rwsem must be held
104  *   for writing while initializing or destroying an object.
105  *
106  * - In addition, each object has a "live" flag.  If this flag is not
107  *   set, then lookups of the object will fail even if it is found in
108  *   the idr.  This handles a reader that blocks and does not acquire
109  *   the rwsem until after the object is destroyed.  The destroy
110  *   operation will set the live flag to 0 and then drop the rwsem;
111  *   this will allow the reader to acquire the rwsem, see that the
112  *   live flag is 0, and then drop the rwsem and its reference to
113  *   object.  The underlying storage will not be freed until the last
114  *   reference to the object is dropped.
115  */
116
117 static void init_uobj(struct ib_uobject *uobj, u64 user_handle,
118                       struct ib_ucontext *context, struct uverbs_lock_class *c)
119 {
120         uobj->user_handle = user_handle;
121         uobj->context     = context;
122         kref_init(&uobj->ref);
123         init_rwsem(&uobj->mutex);
124         lockdep_set_class_and_name(&uobj->mutex, &c->key, c->name);
125         uobj->live        = 0;
126 }
127
128 static void release_uobj(struct kref *kref)
129 {
130         kfree(container_of(kref, struct ib_uobject, ref));
131 }
132
133 static void put_uobj(struct ib_uobject *uobj)
134 {
135         kref_put(&uobj->ref, release_uobj);
136 }
137
138 static void put_uobj_read(struct ib_uobject *uobj)
139 {
140         up_read(&uobj->mutex);
141         put_uobj(uobj);
142 }
143
144 static void put_uobj_write(struct ib_uobject *uobj)
145 {
146         up_write(&uobj->mutex);
147         put_uobj(uobj);
148 }
149
150 static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj)
151 {
152         int ret;
153
154         idr_preload(GFP_KERNEL);
155         spin_lock(&ib_uverbs_idr_lock);
156
157         ret = idr_alloc(idr, uobj, 0, 0, GFP_NOWAIT);
158         if (ret >= 0)
159                 uobj->id = ret;
160
161         spin_unlock(&ib_uverbs_idr_lock);
162         idr_preload_end();
163
164         return ret < 0 ? ret : 0;
165 }
166
167 void idr_remove_uobj(struct idr *idr, struct ib_uobject *uobj)
168 {
169         spin_lock(&ib_uverbs_idr_lock);
170         idr_remove(idr, uobj->id);
171         spin_unlock(&ib_uverbs_idr_lock);
172 }
173
174 static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
175                                          struct ib_ucontext *context)
176 {
177         struct ib_uobject *uobj;
178
179         spin_lock(&ib_uverbs_idr_lock);
180         uobj = idr_find(idr, id);
181         if (uobj) {
182                 if (uobj->context == context)
183                         kref_get(&uobj->ref);
184                 else
185                         uobj = NULL;
186         }
187         spin_unlock(&ib_uverbs_idr_lock);
188
189         return uobj;
190 }
191
192 static struct ib_uobject *idr_read_uobj(struct idr *idr, int id,
193                                         struct ib_ucontext *context, int nested)
194 {
195         struct ib_uobject *uobj;
196
197         uobj = __idr_get_uobj(idr, id, context);
198         if (!uobj)
199                 return NULL;
200
201         if (nested)
202                 down_read_nested(&uobj->mutex, SINGLE_DEPTH_NESTING);
203         else
204                 down_read(&uobj->mutex);
205         if (!uobj->live) {
206                 put_uobj_read(uobj);
207                 return NULL;
208         }
209
210         return uobj;
211 }
212
213 static struct ib_uobject *idr_write_uobj(struct idr *idr, int id,
214                                          struct ib_ucontext *context)
215 {
216         struct ib_uobject *uobj;
217
218         uobj = __idr_get_uobj(idr, id, context);
219         if (!uobj)
220                 return NULL;
221
222         down_write(&uobj->mutex);
223         if (!uobj->live) {
224                 put_uobj_write(uobj);
225                 return NULL;
226         }
227
228         return uobj;
229 }
230
231 static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context,
232                           int nested)
233 {
234         struct ib_uobject *uobj;
235
236         uobj = idr_read_uobj(idr, id, context, nested);
237         return uobj ? uobj->object : NULL;
238 }
239
240 static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context)
241 {
242         return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context, 0);
243 }
244
245 static void put_pd_read(struct ib_pd *pd)
246 {
247         put_uobj_read(pd->uobject);
248 }
249
250 static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context, int nested)
251 {
252         return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context, nested);
253 }
254
255 static void put_cq_read(struct ib_cq *cq)
256 {
257         put_uobj_read(cq->uobject);
258 }
259
260 static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context)
261 {
262         return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context, 0);
263 }
264
265 static void put_ah_read(struct ib_ah *ah)
266 {
267         put_uobj_read(ah->uobject);
268 }
269
270 static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context)
271 {
272         return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0);
273 }
274
275 static struct ib_qp *idr_write_qp(int qp_handle, struct ib_ucontext *context)
276 {
277         struct ib_uobject *uobj;
278
279         uobj = idr_write_uobj(&ib_uverbs_qp_idr, qp_handle, context);
280         return uobj ? uobj->object : NULL;
281 }
282
283 static void put_qp_read(struct ib_qp *qp)
284 {
285         put_uobj_read(qp->uobject);
286 }
287
288 static void put_qp_write(struct ib_qp *qp)
289 {
290         put_uobj_write(qp->uobject);
291 }
292
293 static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context)
294 {
295         return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0);
296 }
297
298 static void put_srq_read(struct ib_srq *srq)
299 {
300         put_uobj_read(srq->uobject);
301 }
302
303 static struct ib_xrcd *idr_read_xrcd(int xrcd_handle, struct ib_ucontext *context,
304                                      struct ib_uobject **uobj)
305 {
306         *uobj = idr_read_uobj(&ib_uverbs_xrcd_idr, xrcd_handle, context, 0);
307         return *uobj ? (*uobj)->object : NULL;
308 }
309
310 static void put_xrcd_read(struct ib_uobject *uobj)
311 {
312         put_uobj_read(uobj);
313 }
314
315 ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
316                               const char __user *buf,
317                               int in_len, int out_len)
318 {
319         struct ib_uverbs_get_context      cmd;
320         struct ib_uverbs_get_context_resp resp;
321         struct ib_udata                   udata;
322         struct ib_device                 *ibdev = file->device->ib_dev;
323 #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
324         struct ib_device_attr             dev_attr;
325 #endif
326         struct ib_ucontext               *ucontext;
327         struct file                      *filp;
328         int ret;
329
330         if (out_len < sizeof resp)
331                 return -ENOSPC;
332
333         if (copy_from_user(&cmd, buf, sizeof cmd))
334                 return -EFAULT;
335
336         mutex_lock(&file->mutex);
337
338         if (file->ucontext) {
339                 ret = -EINVAL;
340                 goto err;
341         }
342
343         INIT_UDATA(&udata, buf + sizeof cmd,
344                    (unsigned long) cmd.response + sizeof resp,
345                    in_len - sizeof cmd, out_len - sizeof resp);
346
347         ucontext = ibdev->alloc_ucontext(ibdev, &udata);
348         if (IS_ERR(ucontext)) {
349                 ret = PTR_ERR(ucontext);
350                 goto err;
351         }
352
353         ucontext->device = ibdev;
354         INIT_LIST_HEAD(&ucontext->pd_list);
355         INIT_LIST_HEAD(&ucontext->mr_list);
356         INIT_LIST_HEAD(&ucontext->mw_list);
357         INIT_LIST_HEAD(&ucontext->cq_list);
358         INIT_LIST_HEAD(&ucontext->qp_list);
359         INIT_LIST_HEAD(&ucontext->srq_list);
360         INIT_LIST_HEAD(&ucontext->ah_list);
361         INIT_LIST_HEAD(&ucontext->xrcd_list);
362         INIT_LIST_HEAD(&ucontext->rule_list);
363         rcu_read_lock();
364         ucontext->tgid = get_task_pid(current->group_leader, PIDTYPE_PID);
365         rcu_read_unlock();
366         ucontext->closing = 0;
367
368 #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
369         ucontext->umem_tree = RB_ROOT;
370         init_rwsem(&ucontext->umem_rwsem);
371         ucontext->odp_mrs_count = 0;
372         INIT_LIST_HEAD(&ucontext->no_private_counters);
373
374         ret = ib_query_device(ibdev, &dev_attr);
375         if (ret)
376                 goto err_free;
377         if (!(dev_attr.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING))
378                 ucontext->invalidate_range = NULL;
379
380 #endif
381
382         resp.num_comp_vectors = file->device->num_comp_vectors;
383
384 #if 0   /* AKAROS */
385         ret = get_unused_fd_flags(O_CLOEXEC);
386         if (ret < 0)
387                 goto err_free;
388         resp.async_fd = ret;
389
390         filp = ib_uverbs_alloc_event_file(file, 1);
391         if (IS_ERR(filp)) {
392                 ret = PTR_ERR(filp);
393                 goto err_fd;
394         }
395 #endif  /* AKAROS */
396
397         if (copy_to_user((void __user *) (unsigned long) cmd.response,
398                          &resp, sizeof resp)) {
399                 ret = -EFAULT;
400                 goto err_file;
401         }
402
403 #if 0   /* AKAROS */
404         file->async_file = filp->private_data;
405 #endif  /* AKAROS */
406
407         INIT_IB_EVENT_HANDLER(&file->event_handler, file->device->ib_dev,
408                               ib_uverbs_event_handler);
409         ret = ib_register_event_handler(&file->event_handler);
410         if (ret)
411                 goto err_file;
412
413 #if 0   /* AKAROS */
414         kref_get(&file->async_file->ref);
415 #endif  /* AKAROS */
416         kref_get(&file->ref);
417         file->ucontext = ucontext;
418
419 #if 0   /* AKAROS */
420         fd_install(resp.async_fd, filp);
421 #endif  /* AKAROS */
422
423         mutex_unlock(&file->mutex);
424
425         return in_len;
426
427 err_file:
428 #if 0   /* AKAROS */
429         fput(filp);
430
431 err_fd:
432         put_unused_fd(resp.async_fd);
433 #endif  /* AKAROS */
434
435 err_free:
436         put_pid(ucontext->tgid);
437         ibdev->dealloc_ucontext(ucontext);
438
439 err:
440         mutex_unlock(&file->mutex);
441         return ret;
442 }
443
444 static void copy_query_dev_fields(struct ib_uverbs_file *file,
445                                   struct ib_uverbs_query_device_resp *resp,
446                                   struct ib_device_attr *attr)
447 {
448         resp->fw_ver            = attr->fw_ver;
449         resp->node_guid         = file->device->ib_dev->node_guid;
450         resp->sys_image_guid    = attr->sys_image_guid;
451         resp->max_mr_size       = attr->max_mr_size;
452         resp->page_size_cap     = attr->page_size_cap;
453         resp->vendor_id         = attr->vendor_id;
454         resp->vendor_part_id    = attr->vendor_part_id;
455         resp->hw_ver            = attr->hw_ver;
456         resp->max_qp            = attr->max_qp;
457         resp->max_qp_wr         = attr->max_qp_wr;
458         resp->device_cap_flags  = attr->device_cap_flags;
459         resp->max_sge           = attr->max_sge;
460         resp->max_sge_rd        = attr->max_sge_rd;
461         resp->max_cq            = attr->max_cq;
462         resp->max_cqe           = attr->max_cqe;
463         resp->max_mr            = attr->max_mr;
464         resp->max_pd            = attr->max_pd;
465         resp->max_qp_rd_atom    = attr->max_qp_rd_atom;
466         resp->max_ee_rd_atom    = attr->max_ee_rd_atom;
467         resp->max_res_rd_atom   = attr->max_res_rd_atom;
468         resp->max_qp_init_rd_atom       = attr->max_qp_init_rd_atom;
469         resp->max_ee_init_rd_atom       = attr->max_ee_init_rd_atom;
470         resp->atomic_cap                = attr->atomic_cap;
471         resp->max_ee                    = attr->max_ee;
472         resp->max_rdd                   = attr->max_rdd;
473         resp->max_mw                    = attr->max_mw;
474         resp->max_raw_ipv6_qp           = attr->max_raw_ipv6_qp;
475         resp->max_raw_ethy_qp           = attr->max_raw_ethy_qp;
476         resp->max_mcast_grp             = attr->max_mcast_grp;
477         resp->max_mcast_qp_attach       = attr->max_mcast_qp_attach;
478         resp->max_total_mcast_qp_attach = attr->max_total_mcast_qp_attach;
479         resp->max_ah                    = attr->max_ah;
480         resp->max_fmr                   = attr->max_fmr;
481         resp->max_map_per_fmr           = attr->max_map_per_fmr;
482         resp->max_srq                   = attr->max_srq;
483         resp->max_srq_wr                = attr->max_srq_wr;
484         resp->max_srq_sge               = attr->max_srq_sge;
485         resp->max_pkeys                 = attr->max_pkeys;
486         resp->local_ca_ack_delay        = attr->local_ca_ack_delay;
487         resp->phys_port_cnt             = file->device->ib_dev->phys_port_cnt;
488 }
489
490 ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
491                                const char __user *buf,
492                                int in_len, int out_len)
493 {
494         struct ib_uverbs_query_device      cmd;
495         struct ib_uverbs_query_device_resp resp;
496         struct ib_device_attr              attr;
497         int                                ret;
498
499         if (out_len < sizeof resp)
500                 return -ENOSPC;
501
502         if (copy_from_user(&cmd, buf, sizeof cmd))
503                 return -EFAULT;
504
505         ret = ib_query_device(file->device->ib_dev, &attr);
506         if (ret)
507                 return ret;
508
509         memset(&resp, 0, sizeof resp);
510         copy_query_dev_fields(file, &resp, &attr);
511
512         if (copy_to_user((void __user *) (unsigned long) cmd.response,
513                          &resp, sizeof resp))
514                 return -EFAULT;
515
516         return in_len;
517 }
518
519 ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
520                              const char __user *buf,
521                              int in_len, int out_len)
522 {
523         struct ib_uverbs_query_port      cmd;
524         struct ib_uverbs_query_port_resp resp;
525         struct ib_port_attr              attr;
526         int                              ret;
527
528         if (out_len < sizeof resp)
529                 return -ENOSPC;
530
531         if (copy_from_user(&cmd, buf, sizeof cmd))
532                 return -EFAULT;
533
534         ret = ib_query_port(file->device->ib_dev, cmd.port_num, &attr);
535         if (ret)
536                 return ret;
537
538         memset(&resp, 0, sizeof resp);
539
540         resp.state           = attr.state;
541         resp.max_mtu         = attr.max_mtu;
542         resp.active_mtu      = attr.active_mtu;
543         resp.gid_tbl_len     = attr.gid_tbl_len;
544         resp.port_cap_flags  = attr.port_cap_flags;
545         resp.max_msg_sz      = attr.max_msg_sz;
546         resp.bad_pkey_cntr   = attr.bad_pkey_cntr;
547         resp.qkey_viol_cntr  = attr.qkey_viol_cntr;
548         resp.pkey_tbl_len    = attr.pkey_tbl_len;
549         resp.lid             = attr.lid;
550         resp.sm_lid          = attr.sm_lid;
551         resp.lmc             = attr.lmc;
552         resp.max_vl_num      = attr.max_vl_num;
553         resp.sm_sl           = attr.sm_sl;
554         resp.subnet_timeout  = attr.subnet_timeout;
555         resp.init_type_reply = attr.init_type_reply;
556         resp.active_width    = attr.active_width;
557         resp.active_speed    = attr.active_speed;
558         resp.phys_state      = attr.phys_state;
559         resp.link_layer      = rdma_port_get_link_layer(file->device->ib_dev,
560                                                         cmd.port_num);
561
562         if (copy_to_user((void __user *) (unsigned long) cmd.response,
563                          &resp, sizeof resp))
564                 return -EFAULT;
565
566         return in_len;
567 }
568
569 ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
570                            const char __user *buf,
571                            int in_len, int out_len)
572 {
573         struct ib_uverbs_alloc_pd      cmd;
574         struct ib_uverbs_alloc_pd_resp resp;
575         struct ib_udata                udata;
576         struct ib_uobject             *uobj;
577         struct ib_pd                  *pd;
578         int                            ret;
579
580         if (out_len < sizeof resp)
581                 return -ENOSPC;
582
583         if (copy_from_user(&cmd, buf, sizeof cmd))
584                 return -EFAULT;
585
586         INIT_UDATA(&udata, buf + sizeof cmd,
587                    (unsigned long) cmd.response + sizeof resp,
588                    in_len - sizeof cmd, out_len - sizeof resp);
589
590         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
591         if (!uobj)
592                 return -ENOMEM;
593
594         init_uobj(uobj, 0, file->ucontext, &pd_lock_class);
595         down_write(&uobj->mutex);
596
597         pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
598                                             file->ucontext, &udata);
599         if (IS_ERR(pd)) {
600                 ret = PTR_ERR(pd);
601                 goto err;
602         }
603
604         pd->device  = file->device->ib_dev;
605         pd->uobject = uobj;
606         atomic_set(&pd->usecnt, 0);
607
608         uobj->object = pd;
609         ret = idr_add_uobj(&ib_uverbs_pd_idr, uobj);
610         if (ret)
611                 goto err_idr;
612
613         memset(&resp, 0, sizeof resp);
614         resp.pd_handle = uobj->id;
615
616         if (copy_to_user((void __user *) (unsigned long) cmd.response,
617                          &resp, sizeof resp)) {
618                 ret = -EFAULT;
619                 goto err_copy;
620         }
621
622         mutex_lock(&file->mutex);
623         list_add_tail(&uobj->list, &file->ucontext->pd_list);
624         mutex_unlock(&file->mutex);
625
626         uobj->live = 1;
627
628         up_write(&uobj->mutex);
629
630         return in_len;
631
632 err_copy:
633         idr_remove_uobj(&ib_uverbs_pd_idr, uobj);
634
635 err_idr:
636         ib_dealloc_pd(pd);
637
638 err:
639         put_uobj_write(uobj);
640         return ret;
641 }
642
643 ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
644                              const char __user *buf,
645                              int in_len, int out_len)
646 {
647         struct ib_uverbs_dealloc_pd cmd;
648         struct ib_uobject          *uobj;
649         int                         ret;
650
651         if (copy_from_user(&cmd, buf, sizeof cmd))
652                 return -EFAULT;
653
654         uobj = idr_write_uobj(&ib_uverbs_pd_idr, cmd.pd_handle, file->ucontext);
655         if (!uobj)
656                 return -EINVAL;
657
658         ret = ib_dealloc_pd(uobj->object);
659         if (!ret)
660                 uobj->live = 0;
661
662         put_uobj_write(uobj);
663
664         if (ret)
665                 return ret;
666
667         idr_remove_uobj(&ib_uverbs_pd_idr, uobj);
668
669         mutex_lock(&file->mutex);
670         list_del(&uobj->list);
671         mutex_unlock(&file->mutex);
672
673         put_uobj(uobj);
674
675         return in_len;
676 }
677
678 #if 0   /* AKAROS */
679
680 struct xrcd_table_entry {
681         struct rb_node  node;
682         struct ib_xrcd *xrcd;
683         struct inode   *inode;
684 };
685
686 static int xrcd_table_insert(struct ib_uverbs_device *dev,
687                             struct inode *inode,
688                             struct ib_xrcd *xrcd)
689 {
690         struct xrcd_table_entry *entry, *scan;
691         struct rb_node **p = &dev->xrcd_tree.rb_node;
692         struct rb_node *parent = NULL;
693
694         entry = kmalloc(sizeof *entry, GFP_KERNEL);
695         if (!entry)
696                 return -ENOMEM;
697
698         entry->xrcd  = xrcd;
699         entry->inode = inode;
700
701         while (*p) {
702                 parent = *p;
703                 scan = rb_entry(parent, struct xrcd_table_entry, node);
704
705                 if (inode < scan->inode) {
706                         p = &(*p)->rb_left;
707                 } else if (inode > scan->inode) {
708                         p = &(*p)->rb_right;
709                 } else {
710                         kfree(entry);
711                         return -EEXIST;
712                 }
713         }
714
715         rb_link_node(&entry->node, parent, p);
716         rb_insert_color(&entry->node, &dev->xrcd_tree);
717         igrab(inode);
718         return 0;
719 }
720
721 static struct xrcd_table_entry *xrcd_table_search(struct ib_uverbs_device *dev,
722                                                   struct inode *inode)
723 {
724         struct xrcd_table_entry *entry;
725         struct rb_node *p = dev->xrcd_tree.rb_node;
726
727         while (p) {
728                 entry = rb_entry(p, struct xrcd_table_entry, node);
729
730                 if (inode < entry->inode)
731                         p = p->rb_left;
732                 else if (inode > entry->inode)
733                         p = p->rb_right;
734                 else
735                         return entry;
736         }
737
738         return NULL;
739 }
740
741 static struct ib_xrcd *find_xrcd(struct ib_uverbs_device *dev, struct inode *inode)
742 {
743         struct xrcd_table_entry *entry;
744
745         entry = xrcd_table_search(dev, inode);
746         if (!entry)
747                 return NULL;
748
749         return entry->xrcd;
750 }
751
752 static void xrcd_table_delete(struct ib_uverbs_device *dev,
753                               struct inode *inode)
754 {
755         struct xrcd_table_entry *entry;
756
757         entry = xrcd_table_search(dev, inode);
758         if (entry) {
759                 iput(inode);
760                 rb_erase(&entry->node, &dev->xrcd_tree);
761                 kfree(entry);
762         }
763 }
764
765 ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
766                             const char __user *buf, int in_len,
767                             int out_len)
768 {
769         struct ib_uverbs_open_xrcd      cmd;
770         struct ib_uverbs_open_xrcd_resp resp;
771         struct ib_udata                 udata;
772         struct ib_uxrcd_object         *obj;
773         struct ib_xrcd                 *xrcd = NULL;
774         struct fd                       f = {NULL, 0};
775         struct inode                   *inode = NULL;
776         int                             ret = 0;
777         int                             new_xrcd = 0;
778
779         if (out_len < sizeof resp)
780                 return -ENOSPC;
781
782         if (copy_from_user(&cmd, buf, sizeof cmd))
783                 return -EFAULT;
784
785         INIT_UDATA(&udata, buf + sizeof cmd,
786                    (unsigned long) cmd.response + sizeof resp,
787                    in_len - sizeof cmd, out_len - sizeof  resp);
788
789         mutex_lock(&file->device->xrcd_tree_mutex);
790
791         if (cmd.fd != -1) {
792                 /* search for file descriptor */
793                 f = fdget(cmd.fd);
794                 if (!f.file) {
795                         ret = -EBADF;
796                         goto err_tree_mutex_unlock;
797                 }
798
799                 inode = file_inode(f.file);
800                 xrcd = find_xrcd(file->device, inode);
801                 if (!xrcd && !(cmd.oflags & O_CREAT)) {
802                         /* no file descriptor. Need CREATE flag */
803                         ret = -EAGAIN;
804                         goto err_tree_mutex_unlock;
805                 }
806
807                 if (xrcd && cmd.oflags & O_EXCL) {
808                         ret = -EINVAL;
809                         goto err_tree_mutex_unlock;
810                 }
811         }
812
813         obj = kmalloc(sizeof *obj, GFP_KERNEL);
814         if (!obj) {
815                 ret = -ENOMEM;
816                 goto err_tree_mutex_unlock;
817         }
818
819         init_uobj(&obj->uobject, 0, file->ucontext, &xrcd_lock_class);
820
821         down_write(&obj->uobject.mutex);
822
823         if (!xrcd) {
824                 xrcd = file->device->ib_dev->alloc_xrcd(file->device->ib_dev,
825                                                         file->ucontext, &udata);
826                 if (IS_ERR(xrcd)) {
827                         ret = PTR_ERR(xrcd);
828                         goto err;
829                 }
830
831                 xrcd->inode   = inode;
832                 xrcd->device  = file->device->ib_dev;
833                 atomic_set(&xrcd->usecnt, 0);
834                 mutex_init(&xrcd->tgt_qp_mutex);
835                 INIT_LIST_HEAD(&xrcd->tgt_qp_list);
836                 new_xrcd = 1;
837         }
838
839         atomic_set(&obj->refcnt, 0);
840         obj->uobject.object = xrcd;
841         ret = idr_add_uobj(&ib_uverbs_xrcd_idr, &obj->uobject);
842         if (ret)
843                 goto err_idr;
844
845         memset(&resp, 0, sizeof resp);
846         resp.xrcd_handle = obj->uobject.id;
847
848         if (inode) {
849                 if (new_xrcd) {
850                         /* create new inode/xrcd table entry */
851                         ret = xrcd_table_insert(file->device, inode, xrcd);
852                         if (ret)
853                                 goto err_insert_xrcd;
854                 }
855                 atomic_inc(&xrcd->usecnt);
856         }
857
858         if (copy_to_user((void __user *) (unsigned long) cmd.response,
859                          &resp, sizeof resp)) {
860                 ret = -EFAULT;
861                 goto err_copy;
862         }
863
864         if (f.file)
865                 fdput(f);
866
867         mutex_lock(&file->mutex);
868         list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list);
869         mutex_unlock(&file->mutex);
870
871         obj->uobject.live = 1;
872         up_write(&obj->uobject.mutex);
873
874         mutex_unlock(&file->device->xrcd_tree_mutex);
875         return in_len;
876
877 err_copy:
878         if (inode) {
879                 if (new_xrcd)
880                         xrcd_table_delete(file->device, inode);
881                 atomic_dec(&xrcd->usecnt);
882         }
883
884 err_insert_xrcd:
885         idr_remove_uobj(&ib_uverbs_xrcd_idr, &obj->uobject);
886
887 err_idr:
888         ib_dealloc_xrcd(xrcd);
889
890 err:
891         put_uobj_write(&obj->uobject);
892
893 err_tree_mutex_unlock:
894         if (f.file)
895                 fdput(f);
896
897         mutex_unlock(&file->device->xrcd_tree_mutex);
898
899         return ret;
900 }
901
902 ssize_t ib_uverbs_close_xrcd(struct ib_uverbs_file *file,
903                              const char __user *buf, int in_len,
904                              int out_len)
905 {
906         struct ib_uverbs_close_xrcd cmd;
907         struct ib_uobject           *uobj;
908         struct ib_xrcd              *xrcd = NULL;
909         struct inode                *inode = NULL;
910         struct ib_uxrcd_object      *obj;
911         int                         live;
912         int                         ret = 0;
913
914         if (copy_from_user(&cmd, buf, sizeof cmd))
915                 return -EFAULT;
916
917         mutex_lock(&file->device->xrcd_tree_mutex);
918         uobj = idr_write_uobj(&ib_uverbs_xrcd_idr, cmd.xrcd_handle, file->ucontext);
919         if (!uobj) {
920                 ret = -EINVAL;
921                 goto out;
922         }
923
924         xrcd  = uobj->object;
925         inode = xrcd->inode;
926         obj   = container_of(uobj, struct ib_uxrcd_object, uobject);
927         if (atomic_read(&obj->refcnt)) {
928                 put_uobj_write(uobj);
929                 ret = -EBUSY;
930                 goto out;
931         }
932
933         if (!inode || atomic_dec_and_test(&xrcd->usecnt)) {
934                 ret = ib_dealloc_xrcd(uobj->object);
935                 if (!ret)
936                         uobj->live = 0;
937         }
938
939         live = uobj->live;
940         if (inode && ret)
941                 atomic_inc(&xrcd->usecnt);
942
943         put_uobj_write(uobj);
944
945         if (ret)
946                 goto out;
947
948         if (inode && !live)
949                 xrcd_table_delete(file->device, inode);
950
951         idr_remove_uobj(&ib_uverbs_xrcd_idr, uobj);
952         mutex_lock(&file->mutex);
953         list_del(&uobj->list);
954         mutex_unlock(&file->mutex);
955
956         put_uobj(uobj);
957         ret = in_len;
958
959 out:
960         mutex_unlock(&file->device->xrcd_tree_mutex);
961         return ret;
962 }
963
964 void ib_uverbs_dealloc_xrcd(struct ib_uverbs_device *dev,
965                             struct ib_xrcd *xrcd)
966 {
967         struct inode *inode;
968
969         inode = xrcd->inode;
970         if (inode && !atomic_dec_and_test(&xrcd->usecnt))
971                 return;
972
973         ib_dealloc_xrcd(xrcd);
974
975         if (inode)
976                 xrcd_table_delete(dev, inode);
977 }
978
979 #else   /* AKAROS */
980 ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
981                             const char __user *buf, int in_len,
982                             int out_len)
983 {
984         return -EBADF;
985 }
986
987 ssize_t ib_uverbs_close_xrcd(struct ib_uverbs_file *file,
988                              const char __user *buf, int in_len,
989                              int out_len)
990 {
991         return -EBADF;
992 }
993
994 void ib_uverbs_dealloc_xrcd(struct ib_uverbs_device *dev,
995                             struct ib_xrcd *xrcd)
996 {
997 }
998 #endif  /* AKAROS */
999
1000 ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
1001                          const char __user *buf, int in_len,
1002                          int out_len)
1003 {
1004         struct ib_uverbs_reg_mr      cmd;
1005         struct ib_uverbs_reg_mr_resp resp;
1006         struct ib_udata              udata;
1007         struct ib_uobject           *uobj;
1008         struct ib_pd                *pd;
1009         struct ib_mr                *mr;
1010         int                          ret;
1011
1012         if (out_len < sizeof resp)
1013                 return -ENOSPC;
1014
1015         if (copy_from_user(&cmd, buf, sizeof cmd))
1016                 return -EFAULT;
1017
1018         INIT_UDATA(&udata, buf + sizeof cmd,
1019                    (unsigned long) cmd.response + sizeof resp,
1020                    in_len - sizeof cmd, out_len - sizeof resp);
1021
1022         if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
1023                 return -EINVAL;
1024
1025         ret = ib_check_mr_access(cmd.access_flags);
1026         if (ret)
1027                 return ret;
1028
1029         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
1030         if (!uobj)
1031                 return -ENOMEM;
1032
1033         init_uobj(uobj, 0, file->ucontext, &mr_lock_class);
1034         down_write(&uobj->mutex);
1035
1036         pd = idr_read_pd(cmd.pd_handle, file->ucontext);
1037         if (!pd) {
1038                 ret = -EINVAL;
1039                 goto err_free;
1040         }
1041
1042         if (cmd.access_flags & IB_ACCESS_ON_DEMAND) {
1043                 struct ib_device_attr attr;
1044
1045                 ret = ib_query_device(pd->device, &attr);
1046                 if (ret || !(attr.device_cap_flags &
1047                                 IB_DEVICE_ON_DEMAND_PAGING)) {
1048                         pr_debug("ODP support not available\n");
1049                         ret = -EINVAL;
1050                         goto err_put;
1051                 }
1052         }
1053
1054         mr = pd->device->reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va,
1055                                      cmd.access_flags, &udata);
1056         if (IS_ERR(mr)) {
1057                 ret = PTR_ERR(mr);
1058                 goto err_put;
1059         }
1060
1061         mr->device  = pd->device;
1062         mr->pd      = pd;
1063         mr->uobject = uobj;
1064         atomic_inc(&pd->usecnt);
1065         atomic_set(&mr->usecnt, 0);
1066
1067         uobj->object = mr;
1068         ret = idr_add_uobj(&ib_uverbs_mr_idr, uobj);
1069         if (ret)
1070                 goto err_unreg;
1071
1072         memset(&resp, 0, sizeof resp);
1073         resp.lkey      = mr->lkey;
1074         resp.rkey      = mr->rkey;
1075         resp.mr_handle = uobj->id;
1076
1077         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1078                          &resp, sizeof resp)) {
1079                 ret = -EFAULT;
1080                 goto err_copy;
1081         }
1082
1083         put_pd_read(pd);
1084
1085         mutex_lock(&file->mutex);
1086         list_add_tail(&uobj->list, &file->ucontext->mr_list);
1087         mutex_unlock(&file->mutex);
1088
1089         uobj->live = 1;
1090
1091         up_write(&uobj->mutex);
1092
1093         return in_len;
1094
1095 err_copy:
1096         idr_remove_uobj(&ib_uverbs_mr_idr, uobj);
1097
1098 err_unreg:
1099         ib_dereg_mr(mr);
1100
1101 err_put:
1102         put_pd_read(pd);
1103
1104 err_free:
1105         put_uobj_write(uobj);
1106         return ret;
1107 }
1108
1109 ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file,
1110                            const char __user *buf, int in_len,
1111                            int out_len)
1112 {
1113         struct ib_uverbs_rereg_mr      cmd;
1114         struct ib_uverbs_rereg_mr_resp resp;
1115         struct ib_udata              udata;
1116         struct ib_pd                *pd = NULL;
1117         struct ib_mr                *mr;
1118         struct ib_pd                *old_pd;
1119         int                          ret;
1120         struct ib_uobject           *uobj;
1121
1122         if (out_len < sizeof(resp))
1123                 return -ENOSPC;
1124
1125         if (copy_from_user(&cmd, buf, sizeof(cmd)))
1126                 return -EFAULT;
1127
1128         INIT_UDATA(&udata, buf + sizeof(cmd),
1129                    (unsigned long) cmd.response + sizeof(resp),
1130                    in_len - sizeof(cmd), out_len - sizeof(resp));
1131
1132         if (cmd.flags & ~IB_MR_REREG_SUPPORTED || !cmd.flags)
1133                 return -EINVAL;
1134
1135         if ((cmd.flags & IB_MR_REREG_TRANS) &&
1136             (!cmd.start || !cmd.hca_va || 0 >= cmd.length ||
1137              (cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK)))
1138                         return -EINVAL;
1139
1140         uobj = idr_write_uobj(&ib_uverbs_mr_idr, cmd.mr_handle,
1141                               file->ucontext);
1142
1143         if (!uobj)
1144                 return -EINVAL;
1145
1146         mr = uobj->object;
1147
1148         if (cmd.flags & IB_MR_REREG_ACCESS) {
1149                 ret = ib_check_mr_access(cmd.access_flags);
1150                 if (ret)
1151                         goto put_uobjs;
1152         }
1153
1154         if (cmd.flags & IB_MR_REREG_PD) {
1155                 pd = idr_read_pd(cmd.pd_handle, file->ucontext);
1156                 if (!pd) {
1157                         ret = -EINVAL;
1158                         goto put_uobjs;
1159                 }
1160         }
1161
1162         if (atomic_read(&mr->usecnt)) {
1163                 ret = -EBUSY;
1164                 goto put_uobj_pd;
1165         }
1166
1167         old_pd = mr->pd;
1168         ret = mr->device->rereg_user_mr(mr, cmd.flags, cmd.start,
1169                                         cmd.length, cmd.hca_va,
1170                                         cmd.access_flags, pd, &udata);
1171         if (!ret) {
1172                 if (cmd.flags & IB_MR_REREG_PD) {
1173                         atomic_inc(&pd->usecnt);
1174                         mr->pd = pd;
1175                         atomic_dec(&old_pd->usecnt);
1176                 }
1177         } else {
1178                 goto put_uobj_pd;
1179         }
1180
1181         memset(&resp, 0, sizeof(resp));
1182         resp.lkey      = mr->lkey;
1183         resp.rkey      = mr->rkey;
1184
1185         if (copy_to_user((void __user *)(unsigned long)cmd.response,
1186                          &resp, sizeof(resp)))
1187                 ret = -EFAULT;
1188         else
1189                 ret = in_len;
1190
1191 put_uobj_pd:
1192         if (cmd.flags & IB_MR_REREG_PD)
1193                 put_pd_read(pd);
1194
1195 put_uobjs:
1196
1197         put_uobj_write(mr->uobject);
1198
1199         return ret;
1200 }
1201
1202 ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
1203                            const char __user *buf, int in_len,
1204                            int out_len)
1205 {
1206         struct ib_uverbs_dereg_mr cmd;
1207         struct ib_mr             *mr;
1208         struct ib_uobject        *uobj;
1209         int                       ret = -EINVAL;
1210
1211         if (copy_from_user(&cmd, buf, sizeof cmd))
1212                 return -EFAULT;
1213
1214         uobj = idr_write_uobj(&ib_uverbs_mr_idr, cmd.mr_handle, file->ucontext);
1215         if (!uobj)
1216                 return -EINVAL;
1217
1218         mr = uobj->object;
1219
1220         ret = ib_dereg_mr(mr);
1221         if (!ret)
1222                 uobj->live = 0;
1223
1224         put_uobj_write(uobj);
1225
1226         if (ret)
1227                 return ret;
1228
1229         idr_remove_uobj(&ib_uverbs_mr_idr, uobj);
1230
1231         mutex_lock(&file->mutex);
1232         list_del(&uobj->list);
1233         mutex_unlock(&file->mutex);
1234
1235         put_uobj(uobj);
1236
1237         return in_len;
1238 }
1239
1240 ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,
1241                          const char __user *buf, int in_len,
1242                          int out_len)
1243 {
1244         struct ib_uverbs_alloc_mw      cmd;
1245         struct ib_uverbs_alloc_mw_resp resp;
1246         struct ib_uobject             *uobj;
1247         struct ib_pd                  *pd;
1248         struct ib_mw                  *mw;
1249         int                            ret;
1250
1251         if (out_len < sizeof(resp))
1252                 return -ENOSPC;
1253
1254         if (copy_from_user(&cmd, buf, sizeof(cmd)))
1255                 return -EFAULT;
1256
1257         uobj = kmalloc(sizeof(*uobj), GFP_KERNEL);
1258         if (!uobj)
1259                 return -ENOMEM;
1260
1261         init_uobj(uobj, 0, file->ucontext, &mw_lock_class);
1262         down_write(&uobj->mutex);
1263
1264         pd = idr_read_pd(cmd.pd_handle, file->ucontext);
1265         if (!pd) {
1266                 ret = -EINVAL;
1267                 goto err_free;
1268         }
1269
1270         mw = pd->device->alloc_mw(pd, cmd.mw_type);
1271         if (IS_ERR(mw)) {
1272                 ret = PTR_ERR(mw);
1273                 goto err_put;
1274         }
1275
1276         mw->device  = pd->device;
1277         mw->pd      = pd;
1278         mw->uobject = uobj;
1279         atomic_inc(&pd->usecnt);
1280
1281         uobj->object = mw;
1282         ret = idr_add_uobj(&ib_uverbs_mw_idr, uobj);
1283         if (ret)
1284                 goto err_unalloc;
1285
1286         memset(&resp, 0, sizeof(resp));
1287         resp.rkey      = mw->rkey;
1288         resp.mw_handle = uobj->id;
1289
1290         if (copy_to_user((void __user *)(unsigned long)cmd.response,
1291                          &resp, sizeof(resp))) {
1292                 ret = -EFAULT;
1293                 goto err_copy;
1294         }
1295
1296         put_pd_read(pd);
1297
1298         mutex_lock(&file->mutex);
1299         list_add_tail(&uobj->list, &file->ucontext->mw_list);
1300         mutex_unlock(&file->mutex);
1301
1302         uobj->live = 1;
1303
1304         up_write(&uobj->mutex);
1305
1306         return in_len;
1307
1308 err_copy:
1309         idr_remove_uobj(&ib_uverbs_mw_idr, uobj);
1310
1311 err_unalloc:
1312         ib_dealloc_mw(mw);
1313
1314 err_put:
1315         put_pd_read(pd);
1316
1317 err_free:
1318         put_uobj_write(uobj);
1319         return ret;
1320 }
1321
1322 ssize_t ib_uverbs_dealloc_mw(struct ib_uverbs_file *file,
1323                            const char __user *buf, int in_len,
1324                            int out_len)
1325 {
1326         struct ib_uverbs_dealloc_mw cmd;
1327         struct ib_mw               *mw;
1328         struct ib_uobject          *uobj;
1329         int                         ret = -EINVAL;
1330
1331         if (copy_from_user(&cmd, buf, sizeof(cmd)))
1332                 return -EFAULT;
1333
1334         uobj = idr_write_uobj(&ib_uverbs_mw_idr, cmd.mw_handle, file->ucontext);
1335         if (!uobj)
1336                 return -EINVAL;
1337
1338         mw = uobj->object;
1339
1340         ret = ib_dealloc_mw(mw);
1341         if (!ret)
1342                 uobj->live = 0;
1343
1344         put_uobj_write(uobj);
1345
1346         if (ret)
1347                 return ret;
1348
1349         idr_remove_uobj(&ib_uverbs_mw_idr, uobj);
1350
1351         mutex_lock(&file->mutex);
1352         list_del(&uobj->list);
1353         mutex_unlock(&file->mutex);
1354
1355         put_uobj(uobj);
1356
1357         return in_len;
1358 }
1359
1360 ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
1361                                       const char __user *buf, int in_len,
1362                                       int out_len)
1363 {
1364         struct ib_uverbs_create_comp_channel       cmd;
1365         struct ib_uverbs_create_comp_channel_resp  resp;
1366         struct file                               *filp;
1367         int ret;
1368
1369         if (out_len < sizeof resp)
1370                 return -ENOSPC;
1371
1372         if (copy_from_user(&cmd, buf, sizeof cmd))
1373                 return -EFAULT;
1374
1375 #if 0   /* AKAROS */
1376         ret = get_unused_fd_flags(O_CLOEXEC);
1377         if (ret < 0)
1378                 return ret;
1379         resp.fd = ret;
1380
1381         filp = ib_uverbs_alloc_event_file(file, 0);
1382         if (IS_ERR(filp)) {
1383                 put_unused_fd(resp.fd);
1384                 return PTR_ERR(filp);
1385         }
1386
1387         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1388                          &resp, sizeof resp)) {
1389                 put_unused_fd(resp.fd);
1390                 fput(filp);
1391                 return -EFAULT;
1392         }
1393
1394         fd_install(resp.fd, filp);
1395 #else
1396         BUG_ON(1);
1397 #endif  /* AKAROS */
1398         return in_len;
1399 }
1400
1401 ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
1402                             const char __user *buf, int in_len,
1403                             int out_len)
1404 {
1405         struct ib_uverbs_create_cq      cmd;
1406         struct ib_uverbs_create_cq_resp resp;
1407         struct ib_udata                 udata;
1408         struct ib_ucq_object           *obj;
1409         struct ib_uverbs_event_file    *ev_file = NULL;
1410         struct ib_cq                   *cq;
1411         int                             ret;
1412
1413         if (out_len < sizeof resp)
1414                 return -ENOSPC;
1415
1416         if (copy_from_user(&cmd, buf, sizeof cmd))
1417                 return -EFAULT;
1418
1419         INIT_UDATA(&udata, buf + sizeof cmd,
1420                    (unsigned long) cmd.response + sizeof resp,
1421                    in_len - sizeof cmd, out_len - sizeof resp);
1422
1423         if (cmd.comp_vector >= file->device->num_comp_vectors)
1424                 return -EINVAL;
1425
1426         obj = kmalloc(sizeof *obj, GFP_KERNEL);
1427         if (!obj)
1428                 return -ENOMEM;
1429
1430         init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &cq_lock_class);
1431         down_write(&obj->uobject.mutex);
1432
1433         if (cmd.comp_channel >= 0) {
1434                 ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel);
1435                 if (!ev_file) {
1436                         ret = -EINVAL;
1437                         goto err;
1438                 }
1439         }
1440
1441         obj->uverbs_file           = file;
1442         obj->comp_events_reported  = 0;
1443         obj->async_events_reported = 0;
1444         INIT_LIST_HEAD(&obj->comp_list);
1445         INIT_LIST_HEAD(&obj->async_list);
1446
1447         cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
1448                                              cmd.comp_vector,
1449                                              file->ucontext, &udata);
1450         if (IS_ERR(cq)) {
1451                 ret = PTR_ERR(cq);
1452                 goto err_file;
1453         }
1454
1455         cq->device        = file->device->ib_dev;
1456         cq->uobject       = &obj->uobject;
1457         cq->comp_handler  = ib_uverbs_comp_handler;
1458         cq->event_handler = ib_uverbs_cq_event_handler;
1459         cq->cq_context    = ev_file;
1460         atomic_set(&cq->usecnt, 0);
1461
1462         obj->uobject.object = cq;
1463         ret = idr_add_uobj(&ib_uverbs_cq_idr, &obj->uobject);
1464         if (ret)
1465                 goto err_free;
1466
1467         memset(&resp, 0, sizeof resp);
1468         resp.cq_handle = obj->uobject.id;
1469         resp.cqe       = cq->cqe;
1470
1471         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1472                          &resp, sizeof resp)) {
1473                 ret = -EFAULT;
1474                 goto err_copy;
1475         }
1476
1477         mutex_lock(&file->mutex);
1478         list_add_tail(&obj->uobject.list, &file->ucontext->cq_list);
1479         mutex_unlock(&file->mutex);
1480
1481         obj->uobject.live = 1;
1482
1483         up_write(&obj->uobject.mutex);
1484
1485         return in_len;
1486
1487 err_copy:
1488         idr_remove_uobj(&ib_uverbs_cq_idr, &obj->uobject);
1489
1490 err_free:
1491         ib_destroy_cq(cq);
1492
1493 err_file:
1494         if (ev_file)
1495                 ib_uverbs_release_ucq(file, ev_file, obj);
1496
1497 err:
1498         put_uobj_write(&obj->uobject);
1499         return ret;
1500 }
1501
1502 ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
1503                             const char __user *buf, int in_len,
1504                             int out_len)
1505 {
1506         struct ib_uverbs_resize_cq      cmd;
1507         struct ib_uverbs_resize_cq_resp resp;
1508         struct ib_udata                 udata;
1509         struct ib_cq                    *cq;
1510         int                             ret = -EINVAL;
1511
1512         if (copy_from_user(&cmd, buf, sizeof cmd))
1513                 return -EFAULT;
1514
1515         INIT_UDATA(&udata, buf + sizeof cmd,
1516                    (unsigned long) cmd.response + sizeof resp,
1517                    in_len - sizeof cmd, out_len - sizeof resp);
1518
1519         cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
1520         if (!cq)
1521                 return -EINVAL;
1522
1523         ret = cq->device->resize_cq(cq, cmd.cqe, &udata);
1524         if (ret)
1525                 goto out;
1526
1527         resp.cqe = cq->cqe;
1528
1529         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1530                          &resp, sizeof resp.cqe))
1531                 ret = -EFAULT;
1532
1533 out:
1534         put_cq_read(cq);
1535
1536         return ret ? ret : in_len;
1537 }
1538
1539 static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
1540 {
1541         struct ib_uverbs_wc tmp;
1542
1543         tmp.wr_id               = wc->wr_id;
1544         tmp.status              = wc->status;
1545         tmp.opcode              = wc->opcode;
1546         tmp.vendor_err          = wc->vendor_err;
1547         tmp.byte_len            = wc->byte_len;
1548         tmp.ex.imm_data         = (__u32 __force) wc->ex.imm_data;
1549         tmp.qp_num              = wc->qp->qp_num;
1550         tmp.src_qp              = wc->src_qp;
1551         tmp.wc_flags            = wc->wc_flags;
1552         tmp.pkey_index          = wc->pkey_index;
1553         tmp.slid                = wc->slid;
1554         tmp.sl                  = wc->sl;
1555         tmp.dlid_path_bits      = wc->dlid_path_bits;
1556         tmp.port_num            = wc->port_num;
1557         tmp.reserved            = 0;
1558
1559         if (copy_to_user(dest, &tmp, sizeof tmp))
1560                 return -EFAULT;
1561
1562         return 0;
1563 }
1564
1565 ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
1566                           const char __user *buf, int in_len,
1567                           int out_len)
1568 {
1569         struct ib_uverbs_poll_cq       cmd;
1570         struct ib_uverbs_poll_cq_resp  resp;
1571         u8 __user                     *header_ptr;
1572         u8 __user                     *data_ptr;
1573         struct ib_cq                  *cq;
1574         struct ib_wc                   wc;
1575         int                            ret;
1576
1577         if (copy_from_user(&cmd, buf, sizeof cmd))
1578                 return -EFAULT;
1579
1580         cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
1581         if (!cq)
1582                 return -EINVAL;
1583
1584         /* we copy a struct ib_uverbs_poll_cq_resp to user space */
1585         header_ptr = (void __user *)(unsigned long) cmd.response;
1586         data_ptr = header_ptr + sizeof resp;
1587
1588         memset(&resp, 0, sizeof resp);
1589         while (resp.count < cmd.ne) {
1590                 ret = ib_poll_cq(cq, 1, &wc);
1591                 if (ret < 0)
1592                         goto out_put;
1593                 if (!ret)
1594                         break;
1595
1596                 ret = copy_wc_to_user(data_ptr, &wc);
1597                 if (ret)
1598                         goto out_put;
1599
1600                 data_ptr += sizeof(struct ib_uverbs_wc);
1601                 ++resp.count;
1602         }
1603
1604         if (copy_to_user(header_ptr, &resp, sizeof resp)) {
1605                 ret = -EFAULT;
1606                 goto out_put;
1607         }
1608
1609         ret = in_len;
1610
1611 out_put:
1612         put_cq_read(cq);
1613         return ret;
1614 }
1615
1616 ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
1617                                 const char __user *buf, int in_len,
1618                                 int out_len)
1619 {
1620         struct ib_uverbs_req_notify_cq cmd;
1621         struct ib_cq                  *cq;
1622
1623         if (copy_from_user(&cmd, buf, sizeof cmd))
1624                 return -EFAULT;
1625
1626         cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
1627         if (!cq)
1628                 return -EINVAL;
1629
1630         ib_req_notify_cq(cq, cmd.solicited_only ?
1631                          IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
1632
1633         put_cq_read(cq);
1634
1635         return in_len;
1636 }
1637
1638 ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
1639                              const char __user *buf, int in_len,
1640                              int out_len)
1641 {
1642         struct ib_uverbs_destroy_cq      cmd;
1643         struct ib_uverbs_destroy_cq_resp resp;
1644         struct ib_uobject               *uobj;
1645         struct ib_cq                    *cq;
1646         struct ib_ucq_object            *obj;
1647         struct ib_uverbs_event_file     *ev_file;
1648         int                              ret = -EINVAL;
1649
1650         if (copy_from_user(&cmd, buf, sizeof cmd))
1651                 return -EFAULT;
1652
1653         uobj = idr_write_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext);
1654         if (!uobj)
1655                 return -EINVAL;
1656         cq      = uobj->object;
1657         ev_file = cq->cq_context;
1658         obj     = container_of(cq->uobject, struct ib_ucq_object, uobject);
1659
1660         ret = ib_destroy_cq(cq);
1661         if (!ret)
1662                 uobj->live = 0;
1663
1664         put_uobj_write(uobj);
1665
1666         if (ret)
1667                 return ret;
1668
1669         idr_remove_uobj(&ib_uverbs_cq_idr, uobj);
1670
1671         mutex_lock(&file->mutex);
1672         list_del(&uobj->list);
1673         mutex_unlock(&file->mutex);
1674
1675         ib_uverbs_release_ucq(file, ev_file, obj);
1676
1677         memset(&resp, 0, sizeof resp);
1678         resp.comp_events_reported  = obj->comp_events_reported;
1679         resp.async_events_reported = obj->async_events_reported;
1680
1681         put_uobj(uobj);
1682
1683         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1684                          &resp, sizeof resp))
1685                 return -EFAULT;
1686
1687         return in_len;
1688 }
1689
1690 ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
1691                             const char __user *buf, int in_len,
1692                             int out_len)
1693 {
1694         struct ib_uverbs_create_qp      cmd;
1695         struct ib_uverbs_create_qp_resp resp;
1696         struct ib_udata                 udata;
1697         struct ib_uqp_object           *obj;
1698         struct ib_device               *device;
1699         struct ib_pd                   *pd = NULL;
1700         struct ib_xrcd                 *xrcd = NULL;
1701         struct ib_uobject              *uninitialized_var(xrcd_uobj);
1702         struct ib_cq                   *scq = NULL, *rcq = NULL;
1703         struct ib_srq                  *srq = NULL;
1704         struct ib_qp                   *qp;
1705         struct ib_qp_init_attr          attr;
1706         int ret;
1707
1708         if (out_len < sizeof resp)
1709                 return -ENOSPC;
1710
1711         if (copy_from_user(&cmd, buf, sizeof cmd))
1712                 return -EFAULT;
1713
1714         if (cmd.qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW))
1715                 return -EPERM;
1716
1717         INIT_UDATA(&udata, buf + sizeof cmd,
1718                    (unsigned long) cmd.response + sizeof resp,
1719                    in_len - sizeof cmd, out_len - sizeof resp);
1720
1721         obj = kzalloc(sizeof *obj, GFP_KERNEL);
1722         if (!obj)
1723                 return -ENOMEM;
1724
1725         init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_class);
1726         down_write(&obj->uevent.uobject.mutex);
1727
1728         if (cmd.qp_type == IB_QPT_XRC_TGT) {
1729                 xrcd = idr_read_xrcd(cmd.pd_handle, file->ucontext, &xrcd_uobj);
1730                 if (!xrcd) {
1731                         ret = -EINVAL;
1732                         goto err_put;
1733                 }
1734                 device = xrcd->device;
1735         } else {
1736                 if (cmd.qp_type == IB_QPT_XRC_INI) {
1737                         cmd.max_recv_wr = cmd.max_recv_sge = 0;
1738                 } else {
1739                         if (cmd.is_srq) {
1740                                 srq = idr_read_srq(cmd.srq_handle, file->ucontext);
1741                                 if (!srq || srq->srq_type != IB_SRQT_BASIC) {
1742                                         ret = -EINVAL;
1743                                         goto err_put;
1744                                 }
1745                         }
1746
1747                         if (cmd.recv_cq_handle != cmd.send_cq_handle) {
1748                                 rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext, 0);
1749                                 if (!rcq) {
1750                                         ret = -EINVAL;
1751                                         goto err_put;
1752                                 }
1753                         }
1754                 }
1755
1756                 scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, !!rcq);
1757                 rcq = rcq ?: scq;
1758                 pd  = idr_read_pd(cmd.pd_handle, file->ucontext);
1759                 if (!pd || !scq) {
1760                         ret = -EINVAL;
1761                         goto err_put;
1762                 }
1763
1764                 device = pd->device;
1765         }
1766
1767         attr.event_handler = ib_uverbs_qp_event_handler;
1768         attr.qp_context    = file;
1769         attr.send_cq       = scq;
1770         attr.recv_cq       = rcq;
1771         attr.srq           = srq;
1772         attr.xrcd          = xrcd;
1773         attr.sq_sig_type   = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
1774         attr.qp_type       = cmd.qp_type;
1775         attr.create_flags  = 0;
1776
1777         attr.cap.max_send_wr     = cmd.max_send_wr;
1778         attr.cap.max_recv_wr     = cmd.max_recv_wr;
1779         attr.cap.max_send_sge    = cmd.max_send_sge;
1780         attr.cap.max_recv_sge    = cmd.max_recv_sge;
1781         attr.cap.max_inline_data = cmd.max_inline_data;
1782
1783         obj->uevent.events_reported     = 0;
1784         INIT_LIST_HEAD(&obj->uevent.event_list);
1785         INIT_LIST_HEAD(&obj->mcast_list);
1786
1787         if (cmd.qp_type == IB_QPT_XRC_TGT)
1788                 qp = ib_create_qp(pd, &attr);
1789         else
1790                 qp = device->create_qp(pd, &attr, &udata);
1791
1792         if (IS_ERR(qp)) {
1793                 ret = PTR_ERR(qp);
1794                 goto err_put;
1795         }
1796
1797         if (cmd.qp_type != IB_QPT_XRC_TGT) {
1798                 qp->real_qp       = qp;
1799                 qp->device        = device;
1800                 qp->pd            = pd;
1801                 qp->send_cq       = attr.send_cq;
1802                 qp->recv_cq       = attr.recv_cq;
1803                 qp->srq           = attr.srq;
1804                 qp->event_handler = attr.event_handler;
1805                 qp->qp_context    = attr.qp_context;
1806                 qp->qp_type       = attr.qp_type;
1807                 atomic_set(&qp->usecnt, 0);
1808                 atomic_inc(&pd->usecnt);
1809                 atomic_inc(&attr.send_cq->usecnt);
1810                 if (attr.recv_cq)
1811                         atomic_inc(&attr.recv_cq->usecnt);
1812                 if (attr.srq)
1813                         atomic_inc(&attr.srq->usecnt);
1814         }
1815         qp->uobject = &obj->uevent.uobject;
1816
1817         obj->uevent.uobject.object = qp;
1818         ret = idr_add_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject);
1819         if (ret)
1820                 goto err_destroy;
1821
1822         memset(&resp, 0, sizeof resp);
1823         resp.qpn             = qp->qp_num;
1824         resp.qp_handle       = obj->uevent.uobject.id;
1825         resp.max_recv_sge    = attr.cap.max_recv_sge;
1826         resp.max_send_sge    = attr.cap.max_send_sge;
1827         resp.max_recv_wr     = attr.cap.max_recv_wr;
1828         resp.max_send_wr     = attr.cap.max_send_wr;
1829         resp.max_inline_data = attr.cap.max_inline_data;
1830
1831         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1832                          &resp, sizeof resp)) {
1833                 ret = -EFAULT;
1834                 goto err_copy;
1835         }
1836
1837         if (xrcd) {
1838                 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
1839                                           uobject);
1840                 atomic_inc(&obj->uxrcd->refcnt);
1841                 put_xrcd_read(xrcd_uobj);
1842         }
1843
1844         if (pd)
1845                 put_pd_read(pd);
1846         if (scq)
1847                 put_cq_read(scq);
1848         if (rcq && rcq != scq)
1849                 put_cq_read(rcq);
1850         if (srq)
1851                 put_srq_read(srq);
1852
1853         mutex_lock(&file->mutex);
1854         list_add_tail(&obj->uevent.uobject.list, &file->ucontext->qp_list);
1855         mutex_unlock(&file->mutex);
1856
1857         obj->uevent.uobject.live = 1;
1858
1859         up_write(&obj->uevent.uobject.mutex);
1860
1861         return in_len;
1862
1863 err_copy:
1864         idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject);
1865
1866 err_destroy:
1867         ib_destroy_qp(qp);
1868
1869 err_put:
1870         if (xrcd)
1871                 put_xrcd_read(xrcd_uobj);
1872         if (pd)
1873                 put_pd_read(pd);
1874         if (scq)
1875                 put_cq_read(scq);
1876         if (rcq && rcq != scq)
1877                 put_cq_read(rcq);
1878         if (srq)
1879                 put_srq_read(srq);
1880
1881         put_uobj_write(&obj->uevent.uobject);
1882         return ret;
1883 }
1884
1885 ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
1886                           const char __user *buf, int in_len, int out_len)
1887 {
1888         struct ib_uverbs_open_qp        cmd;
1889         struct ib_uverbs_create_qp_resp resp;
1890         struct ib_udata                 udata;
1891         struct ib_uqp_object           *obj;
1892         struct ib_xrcd                 *xrcd;
1893         struct ib_uobject              *uninitialized_var(xrcd_uobj);
1894         struct ib_qp                   *qp;
1895         struct ib_qp_open_attr          attr;
1896         int ret;
1897
1898         if (out_len < sizeof resp)
1899                 return -ENOSPC;
1900
1901         if (copy_from_user(&cmd, buf, sizeof cmd))
1902                 return -EFAULT;
1903
1904         INIT_UDATA(&udata, buf + sizeof cmd,
1905                    (unsigned long) cmd.response + sizeof resp,
1906                    in_len - sizeof cmd, out_len - sizeof resp);
1907
1908         obj = kmalloc(sizeof *obj, GFP_KERNEL);
1909         if (!obj)
1910                 return -ENOMEM;
1911
1912         init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_class);
1913         down_write(&obj->uevent.uobject.mutex);
1914
1915         xrcd = idr_read_xrcd(cmd.pd_handle, file->ucontext, &xrcd_uobj);
1916         if (!xrcd) {
1917                 ret = -EINVAL;
1918                 goto err_put;
1919         }
1920
1921         attr.event_handler = ib_uverbs_qp_event_handler;
1922         attr.qp_context    = file;
1923         attr.qp_num        = cmd.qpn;
1924         attr.qp_type       = cmd.qp_type;
1925
1926         obj->uevent.events_reported = 0;
1927         INIT_LIST_HEAD(&obj->uevent.event_list);
1928         INIT_LIST_HEAD(&obj->mcast_list);
1929
1930         qp = ib_open_qp(xrcd, &attr);
1931         if (IS_ERR(qp)) {
1932                 ret = PTR_ERR(qp);
1933                 goto err_put;
1934         }
1935
1936         qp->uobject = &obj->uevent.uobject;
1937
1938         obj->uevent.uobject.object = qp;
1939         ret = idr_add_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject);
1940         if (ret)
1941                 goto err_destroy;
1942
1943         memset(&resp, 0, sizeof resp);
1944         resp.qpn       = qp->qp_num;
1945         resp.qp_handle = obj->uevent.uobject.id;
1946
1947         if (copy_to_user((void __user *) (unsigned long) cmd.response,
1948                          &resp, sizeof resp)) {
1949                 ret = -EFAULT;
1950                 goto err_remove;
1951         }
1952
1953         obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject);
1954         atomic_inc(&obj->uxrcd->refcnt);
1955         put_xrcd_read(xrcd_uobj);
1956
1957         mutex_lock(&file->mutex);
1958         list_add_tail(&obj->uevent.uobject.list, &file->ucontext->qp_list);
1959         mutex_unlock(&file->mutex);
1960
1961         obj->uevent.uobject.live = 1;
1962
1963         up_write(&obj->uevent.uobject.mutex);
1964
1965         return in_len;
1966
1967 err_remove:
1968         idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject);
1969
1970 err_destroy:
1971         ib_destroy_qp(qp);
1972
1973 err_put:
1974         put_xrcd_read(xrcd_uobj);
1975         put_uobj_write(&obj->uevent.uobject);
1976         return ret;
1977 }
1978
1979 ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
1980                            const char __user *buf, int in_len,
1981                            int out_len)
1982 {
1983         struct ib_uverbs_query_qp      cmd;
1984         struct ib_uverbs_query_qp_resp resp;
1985         struct ib_qp                   *qp;
1986         struct ib_qp_attr              *attr;
1987         struct ib_qp_init_attr         *init_attr;
1988         int                            ret;
1989
1990         if (copy_from_user(&cmd, buf, sizeof cmd))
1991                 return -EFAULT;
1992
1993         attr      = kmalloc(sizeof *attr, GFP_KERNEL);
1994         init_attr = kmalloc(sizeof *init_attr, GFP_KERNEL);
1995         if (!attr || !init_attr) {
1996                 ret = -ENOMEM;
1997                 goto out;
1998         }
1999
2000         qp = idr_read_qp(cmd.qp_handle, file->ucontext);
2001         if (!qp) {
2002                 ret = -EINVAL;
2003                 goto out;
2004         }
2005
2006         ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr);
2007
2008         put_qp_read(qp);
2009
2010         if (ret)
2011                 goto out;
2012
2013         memset(&resp, 0, sizeof resp);
2014
2015         resp.qp_state               = attr->qp_state;
2016         resp.cur_qp_state           = attr->cur_qp_state;
2017         resp.path_mtu               = attr->path_mtu;
2018         resp.path_mig_state         = attr->path_mig_state;
2019         resp.qkey                   = attr->qkey;
2020         resp.rq_psn                 = attr->rq_psn;
2021         resp.sq_psn                 = attr->sq_psn;
2022         resp.dest_qp_num            = attr->dest_qp_num;
2023         resp.qp_access_flags        = attr->qp_access_flags;
2024         resp.pkey_index             = attr->pkey_index;
2025         resp.alt_pkey_index         = attr->alt_pkey_index;
2026         resp.sq_draining            = attr->sq_draining;
2027         resp.max_rd_atomic          = attr->max_rd_atomic;
2028         resp.max_dest_rd_atomic     = attr->max_dest_rd_atomic;
2029         resp.min_rnr_timer          = attr->min_rnr_timer;
2030         resp.port_num               = attr->port_num;
2031         resp.timeout                = attr->timeout;
2032         resp.retry_cnt              = attr->retry_cnt;
2033         resp.rnr_retry              = attr->rnr_retry;
2034         resp.alt_port_num           = attr->alt_port_num;
2035         resp.alt_timeout            = attr->alt_timeout;
2036
2037         memcpy(resp.dest.dgid, attr->ah_attr.grh.dgid.raw, 16);
2038         resp.dest.flow_label        = attr->ah_attr.grh.flow_label;
2039         resp.dest.sgid_index        = attr->ah_attr.grh.sgid_index;
2040         resp.dest.hop_limit         = attr->ah_attr.grh.hop_limit;
2041         resp.dest.traffic_class     = attr->ah_attr.grh.traffic_class;
2042         resp.dest.dlid              = attr->ah_attr.dlid;
2043         resp.dest.sl                = attr->ah_attr.sl;
2044         resp.dest.src_path_bits     = attr->ah_attr.src_path_bits;
2045         resp.dest.static_rate       = attr->ah_attr.static_rate;
2046         resp.dest.is_global         = !!(attr->ah_attr.ah_flags & IB_AH_GRH);
2047         resp.dest.port_num          = attr->ah_attr.port_num;
2048
2049         memcpy(resp.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16);
2050         resp.alt_dest.flow_label    = attr->alt_ah_attr.grh.flow_label;
2051         resp.alt_dest.sgid_index    = attr->alt_ah_attr.grh.sgid_index;
2052         resp.alt_dest.hop_limit     = attr->alt_ah_attr.grh.hop_limit;
2053         resp.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class;
2054         resp.alt_dest.dlid          = attr->alt_ah_attr.dlid;
2055         resp.alt_dest.sl            = attr->alt_ah_attr.sl;
2056         resp.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits;
2057         resp.alt_dest.static_rate   = attr->alt_ah_attr.static_rate;
2058         resp.alt_dest.is_global     = !!(attr->alt_ah_attr.ah_flags & IB_AH_GRH);
2059         resp.alt_dest.port_num      = attr->alt_ah_attr.port_num;
2060
2061         resp.max_send_wr            = init_attr->cap.max_send_wr;
2062         resp.max_recv_wr            = init_attr->cap.max_recv_wr;
2063         resp.max_send_sge           = init_attr->cap.max_send_sge;
2064         resp.max_recv_sge           = init_attr->cap.max_recv_sge;
2065         resp.max_inline_data        = init_attr->cap.max_inline_data;
2066         resp.sq_sig_all             = init_attr->sq_sig_type == IB_SIGNAL_ALL_WR;
2067
2068         if (copy_to_user((void __user *) (unsigned long) cmd.response,
2069                          &resp, sizeof resp))
2070                 ret = -EFAULT;
2071
2072 out:
2073         kfree(attr);
2074         kfree(init_attr);
2075
2076         return ret ? ret : in_len;
2077 }
2078
2079 /* Remove ignored fields set in the attribute mask */
2080 static int modify_qp_mask(enum ib_qp_type qp_type, int mask)
2081 {
2082         switch (qp_type) {
2083         case IB_QPT_XRC_INI:
2084                 return mask & ~(IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER);
2085         case IB_QPT_XRC_TGT:
2086                 return mask & ~(IB_QP_MAX_QP_RD_ATOMIC | IB_QP_RETRY_CNT |
2087                                 IB_QP_RNR_RETRY);
2088         default:
2089                 return mask;
2090         }
2091 }
2092
2093 ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
2094                             const char __user *buf, int in_len,
2095                             int out_len)
2096 {
2097         struct ib_uverbs_modify_qp cmd;
2098         struct ib_udata            udata;
2099         struct ib_qp              *qp;
2100         struct ib_qp_attr         *attr;
2101         int                        ret;
2102
2103         if (copy_from_user(&cmd, buf, sizeof cmd))
2104                 return -EFAULT;
2105
2106         INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
2107                    out_len);
2108
2109         attr = kmalloc(sizeof *attr, GFP_KERNEL);
2110         if (!attr)
2111                 return -ENOMEM;
2112
2113         qp = idr_read_qp(cmd.qp_handle, file->ucontext);
2114         if (!qp) {
2115                 ret = -EINVAL;
2116                 goto out;
2117         }
2118
2119         attr->qp_state            = cmd.qp_state;
2120         attr->cur_qp_state        = cmd.cur_qp_state;
2121         attr->path_mtu            = cmd.path_mtu;
2122         attr->path_mig_state      = cmd.path_mig_state;
2123         attr->qkey                = cmd.qkey;
2124         attr->rq_psn              = cmd.rq_psn;
2125         attr->sq_psn              = cmd.sq_psn;
2126         attr->dest_qp_num         = cmd.dest_qp_num;
2127         attr->qp_access_flags     = cmd.qp_access_flags;
2128         attr->pkey_index          = cmd.pkey_index;
2129         attr->alt_pkey_index      = cmd.alt_pkey_index;
2130         attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
2131         attr->max_rd_atomic       = cmd.max_rd_atomic;
2132         attr->max_dest_rd_atomic  = cmd.max_dest_rd_atomic;
2133         attr->min_rnr_timer       = cmd.min_rnr_timer;
2134         attr->port_num            = cmd.port_num;
2135         attr->timeout             = cmd.timeout;
2136         attr->retry_cnt           = cmd.retry_cnt;
2137         attr->rnr_retry           = cmd.rnr_retry;
2138         attr->alt_port_num        = cmd.alt_port_num;
2139         attr->alt_timeout         = cmd.alt_timeout;
2140
2141         memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
2142         attr->ah_attr.grh.flow_label        = cmd.dest.flow_label;
2143         attr->ah_attr.grh.sgid_index        = cmd.dest.sgid_index;
2144         attr->ah_attr.grh.hop_limit         = cmd.dest.hop_limit;
2145         attr->ah_attr.grh.traffic_class     = cmd.dest.traffic_class;
2146         attr->ah_attr.dlid                  = cmd.dest.dlid;
2147         attr->ah_attr.sl                    = cmd.dest.sl;
2148         attr->ah_attr.src_path_bits         = cmd.dest.src_path_bits;
2149         attr->ah_attr.static_rate           = cmd.dest.static_rate;
2150         attr->ah_attr.ah_flags              = cmd.dest.is_global ? IB_AH_GRH : 0;
2151         attr->ah_attr.port_num              = cmd.dest.port_num;
2152
2153         memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
2154         attr->alt_ah_attr.grh.flow_label    = cmd.alt_dest.flow_label;
2155         attr->alt_ah_attr.grh.sgid_index    = cmd.alt_dest.sgid_index;
2156         attr->alt_ah_attr.grh.hop_limit     = cmd.alt_dest.hop_limit;
2157         attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
2158         attr->alt_ah_attr.dlid              = cmd.alt_dest.dlid;
2159         attr->alt_ah_attr.sl                = cmd.alt_dest.sl;
2160         attr->alt_ah_attr.src_path_bits     = cmd.alt_dest.src_path_bits;
2161         attr->alt_ah_attr.static_rate       = cmd.alt_dest.static_rate;
2162         attr->alt_ah_attr.ah_flags          = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
2163         attr->alt_ah_attr.port_num          = cmd.alt_dest.port_num;
2164
2165         if (qp->real_qp == qp) {
2166                 ret = ib_resolve_eth_l2_attrs(qp, attr, &cmd.attr_mask);
2167                 if (ret)
2168                         goto release_qp;
2169                 ret = qp->device->modify_qp(qp, attr,
2170                         modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
2171         } else {
2172                 ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask));
2173         }
2174
2175         if (ret)
2176                 goto release_qp;
2177
2178         ret = in_len;
2179
2180 release_qp:
2181         put_qp_read(qp);
2182
2183 out:
2184         kfree(attr);
2185
2186         return ret;
2187 }
2188
2189 ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
2190                              const char __user *buf, int in_len,
2191                              int out_len)
2192 {
2193         struct ib_uverbs_destroy_qp      cmd;
2194         struct ib_uverbs_destroy_qp_resp resp;
2195         struct ib_uobject               *uobj;
2196         struct ib_qp                    *qp;
2197         struct ib_uqp_object            *obj;
2198         int                              ret = -EINVAL;
2199
2200         if (copy_from_user(&cmd, buf, sizeof cmd))
2201                 return -EFAULT;
2202
2203         memset(&resp, 0, sizeof resp);
2204
2205         uobj = idr_write_uobj(&ib_uverbs_qp_idr, cmd.qp_handle, file->ucontext);
2206         if (!uobj)
2207                 return -EINVAL;
2208         qp  = uobj->object;
2209         obj = container_of(uobj, struct ib_uqp_object, uevent.uobject);
2210
2211         if (!list_empty(&obj->mcast_list)) {
2212                 put_uobj_write(uobj);
2213                 return -EBUSY;
2214         }
2215
2216         ret = ib_destroy_qp(qp);
2217         if (!ret)
2218                 uobj->live = 0;
2219
2220         put_uobj_write(uobj);
2221
2222         if (ret)
2223                 return ret;
2224
2225         if (obj->uxrcd)
2226                 atomic_dec(&obj->uxrcd->refcnt);
2227
2228         idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
2229
2230         mutex_lock(&file->mutex);
2231         list_del(&uobj->list);
2232         mutex_unlock(&file->mutex);
2233
2234         ib_uverbs_release_uevent(file, &obj->uevent);
2235
2236         resp.events_reported = obj->uevent.events_reported;
2237
2238         put_uobj(uobj);
2239
2240         if (copy_to_user((void __user *) (unsigned long) cmd.response,
2241                          &resp, sizeof resp))
2242                 return -EFAULT;
2243
2244         return in_len;
2245 }
2246
2247 ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
2248                             const char __user *buf, int in_len,
2249                             int out_len)
2250 {
2251         struct ib_uverbs_post_send      cmd;
2252         struct ib_uverbs_post_send_resp resp;
2253         struct ib_uverbs_send_wr       *user_wr;
2254         struct ib_send_wr              *wr = NULL, *last, *next, *bad_wr;
2255         struct ib_qp                   *qp;
2256         int                             i, sg_ind;
2257         int                             is_ud;
2258         ssize_t                         ret = -EINVAL;
2259
2260         if (copy_from_user(&cmd, buf, sizeof cmd))
2261                 return -EFAULT;
2262
2263         if (in_len < sizeof cmd + cmd.wqe_size * cmd.wr_count +
2264             cmd.sge_count * sizeof (struct ib_uverbs_sge))
2265                 return -EINVAL;
2266
2267         if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr))
2268                 return -EINVAL;
2269
2270         user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL);
2271         if (!user_wr)
2272                 return -ENOMEM;
2273
2274         qp = idr_read_qp(cmd.qp_handle, file->ucontext);
2275         if (!qp)
2276                 goto out;
2277
2278         is_ud = qp->qp_type == IB_QPT_UD;
2279         sg_ind = 0;
2280         last = NULL;
2281         for (i = 0; i < cmd.wr_count; ++i) {
2282                 if (copy_from_user(user_wr,
2283                                    buf + sizeof cmd + i * cmd.wqe_size,
2284                                    cmd.wqe_size)) {
2285                         ret = -EFAULT;
2286                         goto out_put;
2287                 }
2288
2289                 if (user_wr->num_sge + sg_ind > cmd.sge_count) {
2290                         ret = -EINVAL;
2291                         goto out_put;
2292                 }
2293
2294                 next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
2295                                user_wr->num_sge * sizeof (struct ib_sge),
2296                                GFP_KERNEL);
2297                 if (!next) {
2298                         ret = -ENOMEM;
2299                         goto out_put;
2300                 }
2301
2302                 if (!last)
2303                         wr = next;
2304                 else
2305                         last->next = next;
2306                 last = next;
2307
2308                 next->next       = NULL;
2309                 next->wr_id      = user_wr->wr_id;
2310                 next->num_sge    = user_wr->num_sge;
2311                 next->opcode     = user_wr->opcode;
2312                 next->send_flags = user_wr->send_flags;
2313
2314                 if (is_ud) {
2315                         if (next->opcode != IB_WR_SEND &&
2316                             next->opcode != IB_WR_SEND_WITH_IMM) {
2317                                 ret = -EINVAL;
2318                                 goto out_put;
2319                         }
2320
2321                         next->wr.ud.ah = idr_read_ah(user_wr->wr.ud.ah,
2322                                                      file->ucontext);
2323                         if (!next->wr.ud.ah) {
2324                                 ret = -EINVAL;
2325                                 goto out_put;
2326                         }
2327                         next->wr.ud.remote_qpn  = user_wr->wr.ud.remote_qpn;
2328                         next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey;
2329                         if (next->opcode == IB_WR_SEND_WITH_IMM)
2330                                 next->ex.imm_data =
2331                                         (__be32 __force) user_wr->ex.imm_data;
2332                 } else {
2333                         switch (next->opcode) {
2334                         case IB_WR_RDMA_WRITE_WITH_IMM:
2335                                 next->ex.imm_data =
2336                                         (__be32 __force) user_wr->ex.imm_data;
2337                         case IB_WR_RDMA_WRITE:
2338                         case IB_WR_RDMA_READ:
2339                                 next->wr.rdma.remote_addr =
2340                                         user_wr->wr.rdma.remote_addr;
2341                                 next->wr.rdma.rkey        =
2342                                         user_wr->wr.rdma.rkey;
2343                                 break;
2344                         case IB_WR_SEND_WITH_IMM:
2345                                 next->ex.imm_data =
2346                                         (__be32 __force) user_wr->ex.imm_data;
2347                                 break;
2348                         case IB_WR_SEND_WITH_INV:
2349                                 next->ex.invalidate_rkey =
2350                                         user_wr->ex.invalidate_rkey;
2351                                 break;
2352                         case IB_WR_ATOMIC_CMP_AND_SWP:
2353                         case IB_WR_ATOMIC_FETCH_AND_ADD:
2354                                 next->wr.atomic.remote_addr =
2355                                         user_wr->wr.atomic.remote_addr;
2356                                 next->wr.atomic.compare_add =
2357                                         user_wr->wr.atomic.compare_add;
2358                                 next->wr.atomic.swap = user_wr->wr.atomic.swap;
2359                                 next->wr.atomic.rkey = user_wr->wr.atomic.rkey;
2360                         case IB_WR_SEND:
2361                                 break;
2362                         default:
2363                                 ret = -EINVAL;
2364                                 goto out_put;
2365                         }
2366                 }
2367
2368                 if (next->num_sge) {
2369                         next->sg_list = (void *) next +
2370                                 ALIGN(sizeof *next, sizeof (struct ib_sge));
2371                         if (copy_from_user(next->sg_list,
2372                                            buf + sizeof cmd +
2373                                            cmd.wr_count * cmd.wqe_size +
2374                                            sg_ind * sizeof (struct ib_sge),
2375                                            next->num_sge * sizeof (struct ib_sge))) {
2376                                 ret = -EFAULT;
2377                                 goto out_put;
2378                         }
2379                         sg_ind += next->num_sge;
2380                 } else
2381                         next->sg_list = NULL;
2382         }
2383
2384         resp.bad_wr = 0;
2385         ret = qp->device->post_send(qp->real_qp, wr, &bad_wr);
2386         if (ret)
2387                 for (next = wr; next; next = next->next) {
2388                         ++resp.bad_wr;
2389                         if (next == bad_wr)
2390                                 break;
2391                 }
2392
2393         if (copy_to_user((void __user *) (unsigned long) cmd.response,
2394                          &resp, sizeof resp))
2395                 ret = -EFAULT;
2396
2397 out_put:
2398         put_qp_read(qp);
2399
2400         while (wr) {
2401                 if (is_ud && wr->wr.ud.ah)
2402                         put_ah_read(wr->wr.ud.ah);
2403                 next = wr->next;
2404                 kfree(wr);
2405                 wr = next;
2406         }
2407
2408 out:
2409         kfree(user_wr);
2410
2411         return ret ? ret : in_len;
2412 }
2413
2414 static struct ib_recv_wr *ib_uverbs_unmarshall_recv(const char __user *buf,
2415                                                     int in_len,
2416                                                     u32 wr_count,
2417                                                     u32 sge_count,
2418                                                     u32 wqe_size)
2419 {
2420         struct ib_uverbs_recv_wr *user_wr;
2421         struct ib_recv_wr        *wr = NULL, *last, *next;
2422         int                       sg_ind;
2423         int                       i;
2424         int                       ret;
2425
2426         if (in_len < wqe_size * wr_count +
2427             sge_count * sizeof (struct ib_uverbs_sge))
2428                 return ERR_PTR(-EINVAL);
2429
2430         if (wqe_size < sizeof (struct ib_uverbs_recv_wr))
2431                 return ERR_PTR(-EINVAL);
2432
2433         user_wr = kmalloc(wqe_size, GFP_KERNEL);
2434         if (!user_wr)
2435                 return ERR_PTR(-ENOMEM);
2436
2437         sg_ind = 0;
2438         last = NULL;
2439         for (i = 0; i < wr_count; ++i) {
2440                 if (copy_from_user(user_wr, buf + i * wqe_size,
2441                                    wqe_size)) {
2442                         ret = -EFAULT;
2443                         goto err;
2444                 }
2445
2446                 if (user_wr->num_sge + sg_ind > sge_count) {
2447                         ret = -EINVAL;
2448                         goto err;
2449                 }
2450
2451                 next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
2452                                user_wr->num_sge * sizeof (struct ib_sge),
2453                                GFP_KERNEL);
2454                 if (!next) {
2455                         ret = -ENOMEM;
2456                         goto err;
2457                 }
2458
2459                 if (!last)
2460                         wr = next;
2461                 else
2462                         last->next = next;
2463                 last = next;
2464
2465                 next->next       = NULL;
2466                 next->wr_id      = user_wr->wr_id;
2467                 next->num_sge    = user_wr->num_sge;
2468
2469                 if (next->num_sge) {
2470                         next->sg_list = (void *) next +
2471                                 ALIGN(sizeof *next, sizeof (struct ib_sge));
2472                         if (copy_from_user(next->sg_list,
2473                                            buf + wr_count * wqe_size +
2474                                            sg_ind * sizeof (struct ib_sge),
2475                                            next->num_sge * sizeof (struct ib_sge))) {
2476                                 ret = -EFAULT;
2477                                 goto err;
2478                         }
2479                         sg_ind += next->num_sge;
2480                 } else
2481                         next->sg_list = NULL;
2482         }
2483
2484         kfree(user_wr);
2485         return wr;
2486
2487 err:
2488         kfree(user_wr);
2489
2490         while (wr) {
2491                 next = wr->next;
2492                 kfree(wr);
2493                 wr = next;
2494         }
2495
2496         return ERR_PTR(ret);
2497 }
2498
2499 ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
2500                             const char __user *buf, int in_len,
2501                             int out_len)
2502 {
2503         struct ib_uverbs_post_recv      cmd;
2504         struct ib_uverbs_post_recv_resp resp;
2505         struct ib_recv_wr              *wr, *next, *bad_wr;
2506         struct ib_qp                   *qp;
2507         ssize_t                         ret = -EINVAL;
2508
2509         if (copy_from_user(&cmd, buf, sizeof cmd))
2510                 return -EFAULT;
2511
2512         wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
2513                                        in_len - sizeof cmd, cmd.wr_count,
2514                                        cmd.sge_count, cmd.wqe_size);
2515         if (IS_ERR(wr))
2516                 return PTR_ERR(wr);
2517
2518         qp = idr_read_qp(cmd.qp_handle, file->ucontext);
2519         if (!qp)
2520                 goto out;
2521
2522         resp.bad_wr = 0;
2523         ret = qp->device->post_recv(qp->real_qp, wr, &bad_wr);
2524
2525         put_qp_read(qp);
2526
2527         if (ret)
2528                 for (next = wr; next; next = next->next) {
2529                         ++resp.bad_wr;
2530                         if (next == bad_wr)
2531                                 break;
2532                 }
2533
2534         if (copy_to_user((void __user *) (unsigned long) cmd.response,
2535                          &resp, sizeof resp))
2536                 ret = -EFAULT;
2537
2538 out:
2539         while (wr) {
2540                 next = wr->next;
2541                 kfree(wr);
2542                 wr = next;
2543         }
2544
2545         return ret ? ret : in_len;
2546 }
2547
2548 ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
2549                                 const char __user *buf, int in_len,
2550                                 int out_len)
2551 {
2552         struct ib_uverbs_post_srq_recv      cmd;
2553         struct ib_uverbs_post_srq_recv_resp resp;
2554         struct ib_recv_wr                  *wr, *next, *bad_wr;
2555         struct ib_srq                      *srq;
2556         ssize_t                             ret = -EINVAL;
2557
2558         if (copy_from_user(&cmd, buf, sizeof cmd))
2559                 return -EFAULT;
2560
2561         wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
2562                                        in_len - sizeof cmd, cmd.wr_count,
2563                                        cmd.sge_count, cmd.wqe_size);
2564         if (IS_ERR(wr))
2565                 return PTR_ERR(wr);
2566
2567         srq = idr_read_srq(cmd.srq_handle, file->ucontext);
2568         if (!srq)
2569                 goto out;
2570
2571         resp.bad_wr = 0;
2572         ret = srq->device->post_srq_recv(srq, wr, &bad_wr);
2573
2574         put_srq_read(srq);
2575
2576         if (ret)
2577                 for (next = wr; next; next = next->next) {
2578                         ++resp.bad_wr;
2579                         if (next == bad_wr)
2580                                 break;
2581                 }
2582
2583         if (copy_to_user((void __user *) (unsigned long) cmd.response,
2584                          &resp, sizeof resp))
2585                 ret = -EFAULT;
2586
2587 out:
2588         while (wr) {
2589                 next = wr->next;
2590                 kfree(wr);
2591                 wr = next;
2592         }
2593
2594         return ret ? ret : in_len;
2595 }
2596
2597 ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
2598                             const char __user *buf, int in_len,
2599                             int out_len)
2600 {
2601         struct ib_uverbs_create_ah       cmd;
2602         struct ib_uverbs_create_ah_resp  resp;
2603         struct ib_uobject               *uobj;
2604         struct ib_pd                    *pd;
2605         struct ib_ah                    *ah;
2606         struct ib_ah_attr               attr;
2607         int ret;
2608
2609         if (out_len < sizeof resp)
2610                 return -ENOSPC;
2611
2612         if (copy_from_user(&cmd, buf, sizeof cmd))
2613                 return -EFAULT;
2614
2615         uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
2616         if (!uobj)
2617                 return -ENOMEM;
2618
2619         init_uobj(uobj, cmd.user_handle, file->ucontext, &ah_lock_class);
2620         down_write(&uobj->mutex);
2621
2622         pd = idr_read_pd(cmd.pd_handle, file->ucontext);
2623         if (!pd) {
2624                 ret = -EINVAL;
2625                 goto err;
2626         }
2627
2628         attr.dlid              = cmd.attr.dlid;
2629         attr.sl                = cmd.attr.sl;
2630         attr.src_path_bits     = cmd.attr.src_path_bits;
2631         attr.static_rate       = cmd.attr.static_rate;
2632         attr.ah_flags          = cmd.attr.is_global ? IB_AH_GRH : 0;
2633         attr.port_num          = cmd.attr.port_num;
2634         attr.grh.flow_label    = cmd.attr.grh.flow_label;
2635         attr.grh.sgid_index    = cmd.attr.grh.sgid_index;
2636         attr.grh.hop_limit     = cmd.attr.grh.hop_limit;
2637         attr.grh.traffic_class = cmd.attr.grh.traffic_class;
2638         attr.vlan_id           = 0;
2639         memset(&attr.dmac, 0, sizeof(attr.dmac));
2640         memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16);
2641
2642         ah = ib_create_ah(pd, &attr);
2643         if (IS_ERR(ah)) {
2644                 ret = PTR_ERR(ah);
2645                 goto err_put;
2646         }
2647
2648         ah->uobject  = uobj;
2649         uobj->object = ah;
2650
2651         ret = idr_add_uobj(&ib_uverbs_ah_idr, uobj);
2652         if (ret)
2653                 goto err_destroy;
2654
2655         resp.ah_handle = uobj->id;
2656
2657         if (copy_to_user((void __user *) (unsigned long) cmd.response,
2658                          &resp, sizeof resp)) {
2659                 ret = -EFAULT;
2660                 goto err_copy;
2661         }
2662
2663         put_pd_read(pd);
2664
2665         mutex_lock(&file->mutex);
2666         list_add_tail(&uobj->list, &file->ucontext->ah_list);
2667         mutex_unlock(&file->mutex);
2668
2669         uobj->live = 1;
2670
2671         up_write(&uobj->mutex);
2672
2673         return in_len;
2674
2675 err_copy:
2676         idr_remove_uobj(&ib_uverbs_ah_idr, uobj);
2677
2678 err_destroy:
2679         ib_destroy_ah(ah);
2680
2681 err_put:
2682         put_pd_read(pd);
2683
2684 err:
2685         put_uobj_write(uobj);
2686         return ret;
2687 }
2688
2689 ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
2690                              const char __user *buf, int in_len, int out_len)
2691 {
2692         struct ib_uverbs_destroy_ah cmd;
2693         struct ib_ah               *ah;
2694         struct ib_uobject          *uobj;
2695         int                         ret;
2696
2697         if (copy_from_user(&cmd, buf, sizeof cmd))
2698                 return -EFAULT;
2699
2700         uobj = idr_write_uobj(&ib_uverbs_ah_idr, cmd.ah_handle, file->ucontext);
2701         if (!uobj)
2702                 return -EINVAL;
2703         ah = uobj->object;
2704
2705         ret = ib_destroy_ah(ah);
2706         if (!ret)
2707                 uobj->live = 0;
2708
2709         put_uobj_write(uobj);
2710
2711         if (ret)
2712                 return ret;
2713
2714         idr_remove_uobj(&ib_uverbs_ah_idr, uobj);
2715
2716         mutex_lock(&file->mutex);
2717         list_del(&uobj->list);
2718         mutex_unlock(&file->mutex);
2719
2720         put_uobj(uobj);
2721
2722         return in_len;
2723 }
2724
2725 ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
2726                                const char __user *buf, int in_len,
2727                                int out_len)
2728 {
2729         struct ib_uverbs_attach_mcast cmd;
2730         struct ib_qp                 *qp;
2731         struct ib_uqp_object         *obj;
2732         struct ib_uverbs_mcast_entry *mcast;
2733         int                           ret;
2734
2735         if (copy_from_user(&cmd, buf, sizeof cmd))
2736                 return -EFAULT;
2737
2738         qp = idr_write_qp(cmd.qp_handle, file->ucontext);
2739         if (!qp)
2740                 return -EINVAL;
2741
2742         obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
2743
2744         list_for_each_entry(mcast, &obj->mcast_list, list)
2745                 if (cmd.mlid == mcast->lid &&
2746                     !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
2747                         ret = 0;
2748                         goto out_put;
2749                 }
2750
2751         mcast = kmalloc(sizeof *mcast, GFP_KERNEL);
2752         if (!mcast) {
2753                 ret = -ENOMEM;
2754                 goto out_put;
2755         }
2756
2757         mcast->lid = cmd.mlid;
2758         memcpy(mcast->gid.raw, cmd.gid, sizeof mcast->gid.raw);
2759
2760         ret = ib_attach_mcast(qp, &mcast->gid, cmd.mlid);
2761         if (!ret)
2762                 list_add_tail(&mcast->list, &obj->mcast_list);
2763         else
2764                 kfree(mcast);
2765
2766 out_put:
2767         put_qp_write(qp);
2768
2769         return ret ? ret : in_len;
2770 }
2771
2772 ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
2773                                const char __user *buf, int in_len,
2774                                int out_len)
2775 {
2776         struct ib_uverbs_detach_mcast cmd;
2777         struct ib_uqp_object         *obj;
2778         struct ib_qp                 *qp;
2779         struct ib_uverbs_mcast_entry *mcast;
2780         int                           ret = -EINVAL;
2781
2782         if (copy_from_user(&cmd, buf, sizeof cmd))
2783                 return -EFAULT;
2784
2785         qp = idr_write_qp(cmd.qp_handle, file->ucontext);
2786         if (!qp)
2787                 return -EINVAL;
2788
2789         ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
2790         if (ret)
2791                 goto out_put;
2792
2793         obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
2794
2795         list_for_each_entry(mcast, &obj->mcast_list, list)
2796                 if (cmd.mlid == mcast->lid &&
2797                     !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
2798                         list_del(&mcast->list);
2799                         kfree(mcast);
2800                         break;
2801                 }
2802
2803 out_put:
2804         put_qp_write(qp);
2805
2806         return ret ? ret : in_len;
2807 }
2808
2809 static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec,
2810                                 union ib_flow_spec *ib_spec)
2811 {
2812         if (kern_spec->reserved)
2813                 return -EINVAL;
2814
2815         ib_spec->type = kern_spec->type;
2816
2817         switch (ib_spec->type) {
2818         case IB_FLOW_SPEC_ETH:
2819                 ib_spec->eth.size = sizeof(struct ib_flow_spec_eth);
2820                 if (ib_spec->eth.size != kern_spec->eth.size)
2821                         return -EINVAL;
2822                 memcpy(&ib_spec->eth.val, &kern_spec->eth.val,
2823                        sizeof(struct ib_flow_eth_filter));
2824                 memcpy(&ib_spec->eth.mask, &kern_spec->eth.mask,
2825                        sizeof(struct ib_flow_eth_filter));
2826                 break;
2827         case IB_FLOW_SPEC_IPV4:
2828                 ib_spec->ipv4.size = sizeof(struct ib_flow_spec_ipv4);
2829                 if (ib_spec->ipv4.size != kern_spec->ipv4.size)
2830                         return -EINVAL;
2831                 memcpy(&ib_spec->ipv4.val, &kern_spec->ipv4.val,
2832                        sizeof(struct ib_flow_ipv4_filter));
2833                 memcpy(&ib_spec->ipv4.mask, &kern_spec->ipv4.mask,
2834                        sizeof(struct ib_flow_ipv4_filter));
2835                 break;
2836         case IB_FLOW_SPEC_TCP:
2837         case IB_FLOW_SPEC_UDP:
2838                 ib_spec->tcp_udp.size = sizeof(struct ib_flow_spec_tcp_udp);
2839                 if (ib_spec->tcp_udp.size != kern_spec->tcp_udp.size)
2840                         return -EINVAL;
2841                 memcpy(&ib_spec->tcp_udp.val, &kern_spec->tcp_udp.val,
2842                        sizeof(struct ib_flow_tcp_udp_filter));
2843                 memcpy(&ib_spec->tcp_udp.mask, &kern_spec->tcp_udp.mask,
2844                        sizeof(struct ib_flow_tcp_udp_filter));
2845                 break;
2846         default:
2847                 return -EINVAL;
2848         }
2849         return 0;
2850 }
2851
2852 int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
2853                              struct ib_udata *ucore,
2854                              struct ib_udata *uhw)
2855 {
2856         struct ib_uverbs_create_flow      cmd;
2857         struct ib_uverbs_create_flow_resp resp;
2858         struct ib_uobject                 *uobj;
2859         struct ib_flow                    *flow_id;
2860         struct ib_uverbs_flow_attr        *kern_flow_attr;
2861         struct ib_flow_attr               *flow_attr;
2862         struct ib_qp                      *qp;
2863         int err = 0;
2864         void *kern_spec;
2865         void *ib_spec;
2866         int i;
2867
2868         if (ucore->inlen < sizeof(cmd))
2869                 return -EINVAL;
2870
2871         if (ucore->outlen < sizeof(resp))
2872                 return -ENOSPC;
2873
2874         err = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
2875         if (err)
2876                 return err;
2877
2878         ucore->inbuf += sizeof(cmd);
2879         ucore->inlen -= sizeof(cmd);
2880
2881         if (cmd.comp_mask)
2882                 return -EINVAL;
2883
2884         if ((cmd.flow_attr.type == IB_FLOW_ATTR_SNIFFER &&
2885              !capable(CAP_NET_ADMIN)) || !capable(CAP_NET_RAW))
2886                 return -EPERM;
2887
2888         if (cmd.flow_attr.num_of_specs > IB_FLOW_SPEC_SUPPORT_LAYERS)
2889                 return -EINVAL;
2890
2891         if (cmd.flow_attr.size > ucore->inlen ||
2892             cmd.flow_attr.size >
2893             (cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec)))
2894                 return -EINVAL;
2895
2896         if (cmd.flow_attr.reserved[0] ||
2897             cmd.flow_attr.reserved[1])
2898                 return -EINVAL;
2899
2900         if (cmd.flow_attr.num_of_specs) {
2901                 kern_flow_attr = kmalloc(sizeof(*kern_flow_attr) + cmd.flow_attr.size,
2902                                          GFP_KERNEL);
2903                 if (!kern_flow_attr)
2904                         return -ENOMEM;
2905
2906                 memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr));
2907                 err = ib_copy_from_udata(kern_flow_attr + 1, ucore,
2908                                          cmd.flow_attr.size);
2909                 if (err)
2910                         goto err_free_attr;
2911         } else {
2912                 kern_flow_attr = &cmd.flow_attr;
2913         }
2914
2915         uobj = kmalloc(sizeof(*uobj), GFP_KERNEL);
2916         if (!uobj) {
2917                 err = -ENOMEM;
2918                 goto err_free_attr;
2919         }
2920         init_uobj(uobj, 0, file->ucontext, &rule_lock_class);
2921         down_write(&uobj->mutex);
2922
2923         qp = idr_read_qp(cmd.qp_handle, file->ucontext);
2924         if (!qp) {
2925                 err = -EINVAL;
2926                 goto err_uobj;
2927         }
2928
2929         flow_attr = kmalloc(sizeof(*flow_attr) + cmd.flow_attr.size, GFP_KERNEL);
2930         if (!flow_attr) {
2931                 err = -ENOMEM;
2932                 goto err_put;
2933         }
2934
2935         flow_attr->type = kern_flow_attr->type;
2936         flow_attr->priority = kern_flow_attr->priority;
2937         flow_attr->num_of_specs = kern_flow_attr->num_of_specs;
2938         flow_attr->port = kern_flow_attr->port;
2939         flow_attr->flags = kern_flow_attr->flags;
2940         flow_attr->size = sizeof(*flow_attr);
2941
2942         kern_spec = kern_flow_attr + 1;
2943         ib_spec = flow_attr + 1;
2944         for (i = 0; i < flow_attr->num_of_specs &&
2945              cmd.flow_attr.size > offsetof(struct ib_uverbs_flow_spec, reserved) &&
2946              cmd.flow_attr.size >=
2947              ((struct ib_uverbs_flow_spec *)kern_spec)->size; i++) {
2948                 err = kern_spec_to_ib_spec(kern_spec, ib_spec);
2949                 if (err)
2950                         goto err_free;
2951                 flow_attr->size +=
2952                         ((union ib_flow_spec *) ib_spec)->size;
2953                 cmd.flow_attr.size -= ((struct ib_uverbs_flow_spec *)kern_spec)->size;
2954                 kern_spec += ((struct ib_uverbs_flow_spec *) kern_spec)->size;
2955                 ib_spec += ((union ib_flow_spec *) ib_spec)->size;
2956         }
2957         if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) {
2958                 pr_warn("create flow failed, flow %d: %d bytes left from uverb cmd\n",
2959                         i, cmd.flow_attr.size);
2960                 err = -EINVAL;
2961                 goto err_free;
2962         }
2963         flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER);
2964         if (IS_ERR(flow_id)) {
2965                 err = PTR_ERR(flow_id);
2966                 goto err_free;
2967         }
2968         flow_id->qp = qp;
2969         flow_id->uobject = uobj;
2970         uobj->object = flow_id;
2971
2972         err = idr_add_uobj(&ib_uverbs_rule_idr, uobj);
2973         if (err)
2974                 goto destroy_flow;
2975
2976         memset(&resp, 0, sizeof(resp));
2977         resp.flow_handle = uobj->id;
2978
2979         err = ib_copy_to_udata(ucore,
2980                                &resp, sizeof(resp));
2981         if (err)
2982                 goto err_copy;
2983
2984         put_qp_read(qp);
2985         mutex_lock(&file->mutex);
2986         list_add_tail(&uobj->list, &file->ucontext->rule_list);
2987         mutex_unlock(&file->mutex);
2988
2989         uobj->live = 1;
2990
2991         up_write(&uobj->mutex);
2992         kfree(flow_attr);
2993         if (cmd.flow_attr.num_of_specs)
2994                 kfree(kern_flow_attr);
2995         return 0;
2996 err_copy:
2997         idr_remove_uobj(&ib_uverbs_rule_idr, uobj);
2998 destroy_flow:
2999         ib_destroy_flow(flow_id);
3000 err_free:
3001         kfree(flow_attr);
3002 err_put:
3003         put_qp_read(qp);
3004 err_uobj:
3005         put_uobj_write(uobj);
3006 err_free_attr:
3007         if (cmd.flow_attr.num_of_specs)
3008                 kfree(kern_flow_attr);
3009         return err;
3010 }
3011
3012 int ib_uverbs_ex_destroy_flow(struct ib_uverbs_file *file,
3013                               struct ib_udata *ucore,
3014                               struct ib_udata *uhw)
3015 {
3016         struct ib_uverbs_destroy_flow   cmd;
3017         struct ib_flow                  *flow_id;
3018         struct ib_uobject               *uobj;
3019         int                             ret;
3020
3021         if (ucore->inlen < sizeof(cmd))
3022                 return -EINVAL;
3023
3024         ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
3025         if (ret)
3026                 return ret;
3027
3028         if (cmd.comp_mask)
3029                 return -EINVAL;
3030
3031         uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle,
3032                               file->ucontext);
3033         if (!uobj)
3034                 return -EINVAL;
3035         flow_id = uobj->object;
3036
3037         ret = ib_destroy_flow(flow_id);
3038         if (!ret)
3039                 uobj->live = 0;
3040
3041         put_uobj_write(uobj);
3042
3043         idr_remove_uobj(&ib_uverbs_rule_idr, uobj);
3044
3045         mutex_lock(&file->mutex);
3046         list_del(&uobj->list);
3047         mutex_unlock(&file->mutex);
3048
3049         put_uobj(uobj);
3050
3051         return ret;
3052 }
3053
3054 static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
3055                                 struct ib_uverbs_create_xsrq *cmd,
3056                                 struct ib_udata *udata)
3057 {
3058         struct ib_uverbs_create_srq_resp resp;
3059         struct ib_usrq_object           *obj;
3060         struct ib_pd                    *pd;
3061         struct ib_srq                   *srq;
3062         struct ib_uobject               *uninitialized_var(xrcd_uobj);
3063         struct ib_srq_init_attr          attr;
3064         int ret;
3065
3066         obj = kmalloc(sizeof *obj, GFP_KERNEL);
3067         if (!obj)
3068                 return -ENOMEM;
3069
3070         init_uobj(&obj->uevent.uobject, cmd->user_handle, file->ucontext, &srq_lock_class);
3071         down_write(&obj->uevent.uobject.mutex);
3072
3073         if (cmd->srq_type == IB_SRQT_XRC) {
3074                 attr.ext.xrc.xrcd  = idr_read_xrcd(cmd->xrcd_handle, file->ucontext, &xrcd_uobj);
3075                 if (!attr.ext.xrc.xrcd) {
3076                         ret = -EINVAL;
3077                         goto err;
3078                 }
3079
3080                 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject);
3081                 atomic_inc(&obj->uxrcd->refcnt);
3082
3083                 attr.ext.xrc.cq  = idr_read_cq(cmd->cq_handle, file->ucontext, 0);
3084                 if (!attr.ext.xrc.cq) {
3085                         ret = -EINVAL;
3086                         goto err_put_xrcd;
3087                 }
3088         }
3089
3090         pd  = idr_read_pd(cmd->pd_handle, file->ucontext);
3091         if (!pd) {
3092                 ret = -EINVAL;
3093                 goto err_put_cq;
3094         }
3095
3096         attr.event_handler  = ib_uverbs_srq_event_handler;
3097         attr.srq_context    = file;
3098         attr.srq_type       = cmd->srq_type;
3099         attr.attr.max_wr    = cmd->max_wr;
3100         attr.attr.max_sge   = cmd->max_sge;
3101         attr.attr.srq_limit = cmd->srq_limit;
3102
3103         obj->uevent.events_reported = 0;
3104         INIT_LIST_HEAD(&obj->uevent.event_list);
3105
3106         srq = pd->device->create_srq(pd, &attr, udata);
3107         if (IS_ERR(srq)) {
3108                 ret = PTR_ERR(srq);
3109                 goto err_put;
3110         }
3111
3112         srq->device        = pd->device;
3113         srq->pd            = pd;
3114         srq->srq_type      = cmd->srq_type;
3115         srq->uobject       = &obj->uevent.uobject;
3116         srq->event_handler = attr.event_handler;
3117         srq->srq_context   = attr.srq_context;
3118
3119         if (cmd->srq_type == IB_SRQT_XRC) {
3120                 srq->ext.xrc.cq   = attr.ext.xrc.cq;
3121                 srq->ext.xrc.xrcd = attr.ext.xrc.xrcd;
3122                 atomic_inc(&attr.ext.xrc.cq->usecnt);
3123                 atomic_inc(&attr.ext.xrc.xrcd->usecnt);
3124         }
3125
3126         atomic_inc(&pd->usecnt);
3127         atomic_set(&srq->usecnt, 0);
3128
3129         obj->uevent.uobject.object = srq;
3130         ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject);
3131         if (ret)
3132                 goto err_destroy;
3133
3134         memset(&resp, 0, sizeof resp);
3135         resp.srq_handle = obj->uevent.uobject.id;
3136         resp.max_wr     = attr.attr.max_wr;
3137         resp.max_sge    = attr.attr.max_sge;
3138         if (cmd->srq_type == IB_SRQT_XRC)
3139                 resp.srqn = srq->ext.xrc.srq_num;
3140
3141         if (copy_to_user((void __user *) (unsigned long) cmd->response,
3142                          &resp, sizeof resp)) {
3143                 ret = -EFAULT;
3144                 goto err_copy;
3145         }
3146
3147         if (cmd->srq_type == IB_SRQT_XRC) {
3148                 put_uobj_read(xrcd_uobj);
3149                 put_cq_read(attr.ext.xrc.cq);
3150         }
3151         put_pd_read(pd);
3152
3153         mutex_lock(&file->mutex);
3154         list_add_tail(&obj->uevent.uobject.list, &file->ucontext->srq_list);
3155         mutex_unlock(&file->mutex);
3156
3157         obj->uevent.uobject.live = 1;
3158
3159         up_write(&obj->uevent.uobject.mutex);
3160
3161         return 0;
3162
3163 err_copy:
3164         idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject);
3165
3166 err_destroy:
3167         ib_destroy_srq(srq);
3168
3169 err_put:
3170         put_pd_read(pd);
3171
3172 err_put_cq:
3173         if (cmd->srq_type == IB_SRQT_XRC)
3174                 put_cq_read(attr.ext.xrc.cq);
3175
3176 err_put_xrcd:
3177         if (cmd->srq_type == IB_SRQT_XRC) {
3178                 atomic_dec(&obj->uxrcd->refcnt);
3179                 put_uobj_read(xrcd_uobj);
3180         }
3181
3182 err:
3183         put_uobj_write(&obj->uevent.uobject);
3184         return ret;
3185 }
3186
3187 ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
3188                              const char __user *buf, int in_len,
3189                              int out_len)
3190 {
3191         struct ib_uverbs_create_srq      cmd;
3192         struct ib_uverbs_create_xsrq     xcmd;
3193         struct ib_uverbs_create_srq_resp resp;
3194         struct ib_udata                  udata;
3195         int ret;
3196
3197         if (out_len < sizeof resp)
3198                 return -ENOSPC;
3199
3200         if (copy_from_user(&cmd, buf, sizeof cmd))
3201                 return -EFAULT;
3202
3203         xcmd.response    = cmd.response;
3204         xcmd.user_handle = cmd.user_handle;
3205         xcmd.srq_type    = IB_SRQT_BASIC;
3206         xcmd.pd_handle   = cmd.pd_handle;
3207         xcmd.max_wr      = cmd.max_wr;
3208         xcmd.max_sge     = cmd.max_sge;
3209         xcmd.srq_limit   = cmd.srq_limit;
3210
3211         INIT_UDATA(&udata, buf + sizeof cmd,
3212                    (unsigned long) cmd.response + sizeof resp,
3213                    in_len - sizeof cmd, out_len - sizeof resp);
3214
3215         ret = __uverbs_create_xsrq(file, &xcmd, &udata);
3216         if (ret)
3217                 return ret;
3218
3219         return in_len;
3220 }
3221
3222 ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
3223                               const char __user *buf, int in_len, int out_len)
3224 {
3225         struct ib_uverbs_create_xsrq     cmd;
3226         struct ib_uverbs_create_srq_resp resp;
3227         struct ib_udata                  udata;
3228         int ret;
3229
3230         if (out_len < sizeof resp)
3231                 return -ENOSPC;
3232
3233         if (copy_from_user(&cmd, buf, sizeof cmd))
3234                 return -EFAULT;
3235
3236         INIT_UDATA(&udata, buf + sizeof cmd,
3237                    (unsigned long) cmd.response + sizeof resp,
3238                    in_len - sizeof cmd, out_len - sizeof resp);
3239
3240         ret = __uverbs_create_xsrq(file, &cmd, &udata);
3241         if (ret)
3242                 return ret;
3243
3244         return in_len;
3245 }
3246
3247 ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
3248                              const char __user *buf, int in_len,
3249                              int out_len)
3250 {
3251         struct ib_uverbs_modify_srq cmd;
3252         struct ib_udata             udata;
3253         struct ib_srq              *srq;
3254         struct ib_srq_attr          attr;
3255         int                         ret;
3256
3257 &nbs