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