2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 PathScale, Inc. All rights reserved.
5 * Copyright (c) 2006 Mellanox Technologies. All rights reserved.
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:
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
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.
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
35 * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
38 #include <linux/file.h>
41 #include <asm/uaccess.h>
45 #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
47 (udata)->inbuf = (void __user *) (ibuf); \
48 (udata)->outbuf = (void __user *) (obuf); \
49 (udata)->inlen = (ilen); \
50 (udata)->outlen = (olen); \
53 ssize_t
ib_uverbs_get_context(struct ib_uverbs_file
*file
,
54 const char __user
*buf
,
55 int in_len
, int out_len
)
57 struct ib_uverbs_get_context cmd
;
58 struct ib_uverbs_get_context_resp resp
;
59 struct ib_udata udata
;
60 struct ib_device
*ibdev
= file
->device
->ib_dev
;
61 struct ib_ucontext
*ucontext
;
65 if (out_len
< sizeof resp
)
68 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
71 mutex_lock(&file
->mutex
);
78 INIT_UDATA(&udata
, buf
+ sizeof cmd
,
79 (unsigned long) cmd
.response
+ sizeof resp
,
80 in_len
- sizeof cmd
, out_len
- sizeof resp
);
82 ucontext
= ibdev
->alloc_ucontext(ibdev
, &udata
);
84 return PTR_ERR(file
->ucontext
);
86 ucontext
->device
= ibdev
;
87 INIT_LIST_HEAD(&ucontext
->pd_list
);
88 INIT_LIST_HEAD(&ucontext
->mr_list
);
89 INIT_LIST_HEAD(&ucontext
->mw_list
);
90 INIT_LIST_HEAD(&ucontext
->cq_list
);
91 INIT_LIST_HEAD(&ucontext
->qp_list
);
92 INIT_LIST_HEAD(&ucontext
->srq_list
);
93 INIT_LIST_HEAD(&ucontext
->ah_list
);
95 resp
.num_comp_vectors
= file
->device
->num_comp_vectors
;
97 filp
= ib_uverbs_alloc_event_file(file
, 1, &resp
.async_fd
);
103 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
104 &resp
, sizeof resp
)) {
109 file
->async_file
= filp
->private_data
;
111 INIT_IB_EVENT_HANDLER(&file
->event_handler
, file
->device
->ib_dev
,
112 ib_uverbs_event_handler
);
113 ret
= ib_register_event_handler(&file
->event_handler
);
117 kref_get(&file
->async_file
->ref
);
118 kref_get(&file
->ref
);
119 file
->ucontext
= ucontext
;
121 fd_install(resp
.async_fd
, filp
);
123 mutex_unlock(&file
->mutex
);
128 put_unused_fd(resp
.async_fd
);
132 ibdev
->dealloc_ucontext(ucontext
);
135 mutex_unlock(&file
->mutex
);
139 ssize_t
ib_uverbs_query_device(struct ib_uverbs_file
*file
,
140 const char __user
*buf
,
141 int in_len
, int out_len
)
143 struct ib_uverbs_query_device cmd
;
144 struct ib_uverbs_query_device_resp resp
;
145 struct ib_device_attr attr
;
148 if (out_len
< sizeof resp
)
151 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
154 ret
= ib_query_device(file
->device
->ib_dev
, &attr
);
158 memset(&resp
, 0, sizeof resp
);
160 resp
.fw_ver
= attr
.fw_ver
;
161 resp
.node_guid
= file
->device
->ib_dev
->node_guid
;
162 resp
.sys_image_guid
= attr
.sys_image_guid
;
163 resp
.max_mr_size
= attr
.max_mr_size
;
164 resp
.page_size_cap
= attr
.page_size_cap
;
165 resp
.vendor_id
= attr
.vendor_id
;
166 resp
.vendor_part_id
= attr
.vendor_part_id
;
167 resp
.hw_ver
= attr
.hw_ver
;
168 resp
.max_qp
= attr
.max_qp
;
169 resp
.max_qp_wr
= attr
.max_qp_wr
;
170 resp
.device_cap_flags
= attr
.device_cap_flags
;
171 resp
.max_sge
= attr
.max_sge
;
172 resp
.max_sge_rd
= attr
.max_sge_rd
;
173 resp
.max_cq
= attr
.max_cq
;
174 resp
.max_cqe
= attr
.max_cqe
;
175 resp
.max_mr
= attr
.max_mr
;
176 resp
.max_pd
= attr
.max_pd
;
177 resp
.max_qp_rd_atom
= attr
.max_qp_rd_atom
;
178 resp
.max_ee_rd_atom
= attr
.max_ee_rd_atom
;
179 resp
.max_res_rd_atom
= attr
.max_res_rd_atom
;
180 resp
.max_qp_init_rd_atom
= attr
.max_qp_init_rd_atom
;
181 resp
.max_ee_init_rd_atom
= attr
.max_ee_init_rd_atom
;
182 resp
.atomic_cap
= attr
.atomic_cap
;
183 resp
.max_ee
= attr
.max_ee
;
184 resp
.max_rdd
= attr
.max_rdd
;
185 resp
.max_mw
= attr
.max_mw
;
186 resp
.max_raw_ipv6_qp
= attr
.max_raw_ipv6_qp
;
187 resp
.max_raw_ethy_qp
= attr
.max_raw_ethy_qp
;
188 resp
.max_mcast_grp
= attr
.max_mcast_grp
;
189 resp
.max_mcast_qp_attach
= attr
.max_mcast_qp_attach
;
190 resp
.max_total_mcast_qp_attach
= attr
.max_total_mcast_qp_attach
;
191 resp
.max_ah
= attr
.max_ah
;
192 resp
.max_fmr
= attr
.max_fmr
;
193 resp
.max_map_per_fmr
= attr
.max_map_per_fmr
;
194 resp
.max_srq
= attr
.max_srq
;
195 resp
.max_srq_wr
= attr
.max_srq_wr
;
196 resp
.max_srq_sge
= attr
.max_srq_sge
;
197 resp
.max_pkeys
= attr
.max_pkeys
;
198 resp
.local_ca_ack_delay
= attr
.local_ca_ack_delay
;
199 resp
.phys_port_cnt
= file
->device
->ib_dev
->phys_port_cnt
;
201 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
208 ssize_t
ib_uverbs_query_port(struct ib_uverbs_file
*file
,
209 const char __user
*buf
,
210 int in_len
, int out_len
)
212 struct ib_uverbs_query_port cmd
;
213 struct ib_uverbs_query_port_resp resp
;
214 struct ib_port_attr attr
;
217 if (out_len
< sizeof resp
)
220 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
223 ret
= ib_query_port(file
->device
->ib_dev
, cmd
.port_num
, &attr
);
227 memset(&resp
, 0, sizeof resp
);
229 resp
.state
= attr
.state
;
230 resp
.max_mtu
= attr
.max_mtu
;
231 resp
.active_mtu
= attr
.active_mtu
;
232 resp
.gid_tbl_len
= attr
.gid_tbl_len
;
233 resp
.port_cap_flags
= attr
.port_cap_flags
;
234 resp
.max_msg_sz
= attr
.max_msg_sz
;
235 resp
.bad_pkey_cntr
= attr
.bad_pkey_cntr
;
236 resp
.qkey_viol_cntr
= attr
.qkey_viol_cntr
;
237 resp
.pkey_tbl_len
= attr
.pkey_tbl_len
;
239 resp
.sm_lid
= attr
.sm_lid
;
241 resp
.max_vl_num
= attr
.max_vl_num
;
242 resp
.sm_sl
= attr
.sm_sl
;
243 resp
.subnet_timeout
= attr
.subnet_timeout
;
244 resp
.init_type_reply
= attr
.init_type_reply
;
245 resp
.active_width
= attr
.active_width
;
246 resp
.active_speed
= attr
.active_speed
;
247 resp
.phys_state
= attr
.phys_state
;
249 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
256 ssize_t
ib_uverbs_alloc_pd(struct ib_uverbs_file
*file
,
257 const char __user
*buf
,
258 int in_len
, int out_len
)
260 struct ib_uverbs_alloc_pd cmd
;
261 struct ib_uverbs_alloc_pd_resp resp
;
262 struct ib_udata udata
;
263 struct ib_uobject
*uobj
;
267 if (out_len
< sizeof resp
)
270 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
273 INIT_UDATA(&udata
, buf
+ sizeof cmd
,
274 (unsigned long) cmd
.response
+ sizeof resp
,
275 in_len
- sizeof cmd
, out_len
- sizeof resp
);
277 uobj
= kmalloc(sizeof *uobj
, GFP_KERNEL
);
281 uobj
->context
= file
->ucontext
;
283 pd
= file
->device
->ib_dev
->alloc_pd(file
->device
->ib_dev
,
284 file
->ucontext
, &udata
);
290 pd
->device
= file
->device
->ib_dev
;
292 atomic_set(&pd
->usecnt
, 0);
294 mutex_lock(&ib_uverbs_idr_mutex
);
297 if (!idr_pre_get(&ib_uverbs_pd_idr
, GFP_KERNEL
)) {
302 ret
= idr_get_new(&ib_uverbs_pd_idr
, pd
, &uobj
->id
);
309 memset(&resp
, 0, sizeof resp
);
310 resp
.pd_handle
= uobj
->id
;
312 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
313 &resp
, sizeof resp
)) {
318 mutex_lock(&file
->mutex
);
319 list_add_tail(&uobj
->list
, &file
->ucontext
->pd_list
);
320 mutex_unlock(&file
->mutex
);
322 mutex_unlock(&ib_uverbs_idr_mutex
);
327 idr_remove(&ib_uverbs_pd_idr
, uobj
->id
);
330 mutex_unlock(&ib_uverbs_idr_mutex
);
338 ssize_t
ib_uverbs_dealloc_pd(struct ib_uverbs_file
*file
,
339 const char __user
*buf
,
340 int in_len
, int out_len
)
342 struct ib_uverbs_dealloc_pd cmd
;
344 struct ib_uobject
*uobj
;
347 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
350 mutex_lock(&ib_uverbs_idr_mutex
);
352 pd
= idr_find(&ib_uverbs_pd_idr
, cmd
.pd_handle
);
353 if (!pd
|| pd
->uobject
->context
!= file
->ucontext
)
358 ret
= ib_dealloc_pd(pd
);
362 idr_remove(&ib_uverbs_pd_idr
, cmd
.pd_handle
);
364 mutex_lock(&file
->mutex
);
365 list_del(&uobj
->list
);
366 mutex_unlock(&file
->mutex
);
371 mutex_unlock(&ib_uverbs_idr_mutex
);
373 return ret
? ret
: in_len
;
376 ssize_t
ib_uverbs_reg_mr(struct ib_uverbs_file
*file
,
377 const char __user
*buf
, int in_len
,
380 struct ib_uverbs_reg_mr cmd
;
381 struct ib_uverbs_reg_mr_resp resp
;
382 struct ib_udata udata
;
383 struct ib_umem_object
*obj
;
388 if (out_len
< sizeof resp
)
391 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
394 INIT_UDATA(&udata
, buf
+ sizeof cmd
,
395 (unsigned long) cmd
.response
+ sizeof resp
,
396 in_len
- sizeof cmd
, out_len
- sizeof resp
);
398 if ((cmd
.start
& ~PAGE_MASK
) != (cmd
.hca_va
& ~PAGE_MASK
))
402 * Local write permission is required if remote write or
403 * remote atomic permission is also requested.
405 if (cmd
.access_flags
& (IB_ACCESS_REMOTE_ATOMIC
| IB_ACCESS_REMOTE_WRITE
) &&
406 !(cmd
.access_flags
& IB_ACCESS_LOCAL_WRITE
))
409 obj
= kmalloc(sizeof *obj
, GFP_KERNEL
);
413 obj
->uobject
.context
= file
->ucontext
;
416 * We ask for writable memory if any access flags other than
417 * "remote read" are set. "Local write" and "remote write"
418 * obviously require write access. "Remote atomic" can do
419 * things like fetch and add, which will modify memory, and
420 * "MW bind" can change permissions by binding a window.
422 ret
= ib_umem_get(file
->device
->ib_dev
, &obj
->umem
,
423 (void *) (unsigned long) cmd
.start
, cmd
.length
,
424 !!(cmd
.access_flags
& ~IB_ACCESS_REMOTE_READ
));
428 obj
->umem
.virt_base
= cmd
.hca_va
;
430 mutex_lock(&ib_uverbs_idr_mutex
);
432 pd
= idr_find(&ib_uverbs_pd_idr
, cmd
.pd_handle
);
433 if (!pd
|| pd
->uobject
->context
!= file
->ucontext
) {
438 if (!pd
->device
->reg_user_mr
) {
443 mr
= pd
->device
->reg_user_mr(pd
, &obj
->umem
, cmd
.access_flags
, &udata
);
449 mr
->device
= pd
->device
;
451 mr
->uobject
= &obj
->uobject
;
452 atomic_inc(&pd
->usecnt
);
453 atomic_set(&mr
->usecnt
, 0);
455 memset(&resp
, 0, sizeof resp
);
456 resp
.lkey
= mr
->lkey
;
457 resp
.rkey
= mr
->rkey
;
460 if (!idr_pre_get(&ib_uverbs_mr_idr
, GFP_KERNEL
)) {
465 ret
= idr_get_new(&ib_uverbs_mr_idr
, mr
, &obj
->uobject
.id
);
472 resp
.mr_handle
= obj
->uobject
.id
;
474 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
475 &resp
, sizeof resp
)) {
480 mutex_lock(&file
->mutex
);
481 list_add_tail(&obj
->uobject
.list
, &file
->ucontext
->mr_list
);
482 mutex_unlock(&file
->mutex
);
484 mutex_unlock(&ib_uverbs_idr_mutex
);
489 idr_remove(&ib_uverbs_mr_idr
, obj
->uobject
.id
);
493 atomic_dec(&pd
->usecnt
);
496 mutex_unlock(&ib_uverbs_idr_mutex
);
498 ib_umem_release(file
->device
->ib_dev
, &obj
->umem
);
505 ssize_t
ib_uverbs_dereg_mr(struct ib_uverbs_file
*file
,
506 const char __user
*buf
, int in_len
,
509 struct ib_uverbs_dereg_mr cmd
;
511 struct ib_umem_object
*memobj
;
514 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
517 mutex_lock(&ib_uverbs_idr_mutex
);
519 mr
= idr_find(&ib_uverbs_mr_idr
, cmd
.mr_handle
);
520 if (!mr
|| mr
->uobject
->context
!= file
->ucontext
)
523 memobj
= container_of(mr
->uobject
, struct ib_umem_object
, uobject
);
525 ret
= ib_dereg_mr(mr
);
529 idr_remove(&ib_uverbs_mr_idr
, cmd
.mr_handle
);
531 mutex_lock(&file
->mutex
);
532 list_del(&memobj
->uobject
.list
);
533 mutex_unlock(&file
->mutex
);
535 ib_umem_release(file
->device
->ib_dev
, &memobj
->umem
);
539 mutex_unlock(&ib_uverbs_idr_mutex
);
541 return ret
? ret
: in_len
;
544 ssize_t
ib_uverbs_create_comp_channel(struct ib_uverbs_file
*file
,
545 const char __user
*buf
, int in_len
,
548 struct ib_uverbs_create_comp_channel cmd
;
549 struct ib_uverbs_create_comp_channel_resp resp
;
552 if (out_len
< sizeof resp
)
555 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
558 filp
= ib_uverbs_alloc_event_file(file
, 0, &resp
.fd
);
560 return PTR_ERR(filp
);
562 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
563 &resp
, sizeof resp
)) {
564 put_unused_fd(resp
.fd
);
569 fd_install(resp
.fd
, filp
);
573 ssize_t
ib_uverbs_create_cq(struct ib_uverbs_file
*file
,
574 const char __user
*buf
, int in_len
,
577 struct ib_uverbs_create_cq cmd
;
578 struct ib_uverbs_create_cq_resp resp
;
579 struct ib_udata udata
;
580 struct ib_ucq_object
*uobj
;
581 struct ib_uverbs_event_file
*ev_file
= NULL
;
585 if (out_len
< sizeof resp
)
588 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
591 INIT_UDATA(&udata
, buf
+ sizeof cmd
,
592 (unsigned long) cmd
.response
+ sizeof resp
,
593 in_len
- sizeof cmd
, out_len
- sizeof resp
);
595 if (cmd
.comp_vector
>= file
->device
->num_comp_vectors
)
598 uobj
= kmalloc(sizeof *uobj
, GFP_KERNEL
);
602 if (cmd
.comp_channel
>= 0) {
603 ev_file
= ib_uverbs_lookup_comp_file(cmd
.comp_channel
);
610 uobj
->uobject
.user_handle
= cmd
.user_handle
;
611 uobj
->uobject
.context
= file
->ucontext
;
612 uobj
->uverbs_file
= file
;
613 uobj
->comp_events_reported
= 0;
614 uobj
->async_events_reported
= 0;
615 INIT_LIST_HEAD(&uobj
->comp_list
);
616 INIT_LIST_HEAD(&uobj
->async_list
);
618 cq
= file
->device
->ib_dev
->create_cq(file
->device
->ib_dev
, cmd
.cqe
,
619 file
->ucontext
, &udata
);
625 cq
->device
= file
->device
->ib_dev
;
626 cq
->uobject
= &uobj
->uobject
;
627 cq
->comp_handler
= ib_uverbs_comp_handler
;
628 cq
->event_handler
= ib_uverbs_cq_event_handler
;
629 cq
->cq_context
= ev_file
;
630 atomic_set(&cq
->usecnt
, 0);
632 mutex_lock(&ib_uverbs_idr_mutex
);
635 if (!idr_pre_get(&ib_uverbs_cq_idr
, GFP_KERNEL
)) {
640 ret
= idr_get_new(&ib_uverbs_cq_idr
, cq
, &uobj
->uobject
.id
);
647 memset(&resp
, 0, sizeof resp
);
648 resp
.cq_handle
= uobj
->uobject
.id
;
651 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
652 &resp
, sizeof resp
)) {
657 mutex_lock(&file
->mutex
);
658 list_add_tail(&uobj
->uobject
.list
, &file
->ucontext
->cq_list
);
659 mutex_unlock(&file
->mutex
);
661 mutex_unlock(&ib_uverbs_idr_mutex
);
666 idr_remove(&ib_uverbs_cq_idr
, uobj
->uobject
.id
);
669 mutex_unlock(&ib_uverbs_idr_mutex
);
674 ib_uverbs_release_ucq(file
, ev_file
, uobj
);
679 ssize_t
ib_uverbs_resize_cq(struct ib_uverbs_file
*file
,
680 const char __user
*buf
, int in_len
,
683 struct ib_uverbs_resize_cq cmd
;
684 struct ib_uverbs_resize_cq_resp resp
;
685 struct ib_udata udata
;
689 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
692 INIT_UDATA(&udata
, buf
+ sizeof cmd
,
693 (unsigned long) cmd
.response
+ sizeof resp
,
694 in_len
- sizeof cmd
, out_len
- sizeof resp
);
696 mutex_lock(&ib_uverbs_idr_mutex
);
698 cq
= idr_find(&ib_uverbs_cq_idr
, cmd
.cq_handle
);
699 if (!cq
|| cq
->uobject
->context
!= file
->ucontext
|| !cq
->device
->resize_cq
)
702 ret
= cq
->device
->resize_cq(cq
, cmd
.cqe
, &udata
);
706 memset(&resp
, 0, sizeof resp
);
709 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
714 mutex_unlock(&ib_uverbs_idr_mutex
);
716 return ret
? ret
: in_len
;
719 ssize_t
ib_uverbs_poll_cq(struct ib_uverbs_file
*file
,
720 const char __user
*buf
, int in_len
,
723 struct ib_uverbs_poll_cq cmd
;
724 struct ib_uverbs_poll_cq_resp
*resp
;
731 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
734 wc
= kmalloc(cmd
.ne
* sizeof *wc
, GFP_KERNEL
);
738 rsize
= sizeof *resp
+ cmd
.ne
* sizeof(struct ib_uverbs_wc
);
739 resp
= kmalloc(rsize
, GFP_KERNEL
);
745 mutex_lock(&ib_uverbs_idr_mutex
);
746 cq
= idr_find(&ib_uverbs_cq_idr
, cmd
.cq_handle
);
747 if (!cq
|| cq
->uobject
->context
!= file
->ucontext
) {
752 resp
->count
= ib_poll_cq(cq
, cmd
.ne
, wc
);
754 for (i
= 0; i
< resp
->count
; i
++) {
755 resp
->wc
[i
].wr_id
= wc
[i
].wr_id
;
756 resp
->wc
[i
].status
= wc
[i
].status
;
757 resp
->wc
[i
].opcode
= wc
[i
].opcode
;
758 resp
->wc
[i
].vendor_err
= wc
[i
].vendor_err
;
759 resp
->wc
[i
].byte_len
= wc
[i
].byte_len
;
760 resp
->wc
[i
].imm_data
= (__u32 __force
) wc
[i
].imm_data
;
761 resp
->wc
[i
].qp_num
= wc
[i
].qp_num
;
762 resp
->wc
[i
].src_qp
= wc
[i
].src_qp
;
763 resp
->wc
[i
].wc_flags
= wc
[i
].wc_flags
;
764 resp
->wc
[i
].pkey_index
= wc
[i
].pkey_index
;
765 resp
->wc
[i
].slid
= wc
[i
].slid
;
766 resp
->wc
[i
].sl
= wc
[i
].sl
;
767 resp
->wc
[i
].dlid_path_bits
= wc
[i
].dlid_path_bits
;
768 resp
->wc
[i
].port_num
= wc
[i
].port_num
;
771 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
, resp
, rsize
))
775 mutex_unlock(&ib_uverbs_idr_mutex
);
780 return ret
? ret
: in_len
;
783 ssize_t
ib_uverbs_req_notify_cq(struct ib_uverbs_file
*file
,
784 const char __user
*buf
, int in_len
,
787 struct ib_uverbs_req_notify_cq cmd
;
791 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
794 mutex_lock(&ib_uverbs_idr_mutex
);
795 cq
= idr_find(&ib_uverbs_cq_idr
, cmd
.cq_handle
);
796 if (cq
&& cq
->uobject
->context
== file
->ucontext
) {
797 ib_req_notify_cq(cq
, cmd
.solicited_only
?
798 IB_CQ_SOLICITED
: IB_CQ_NEXT_COMP
);
801 mutex_unlock(&ib_uverbs_idr_mutex
);
806 ssize_t
ib_uverbs_destroy_cq(struct ib_uverbs_file
*file
,
807 const char __user
*buf
, int in_len
,
810 struct ib_uverbs_destroy_cq cmd
;
811 struct ib_uverbs_destroy_cq_resp resp
;
813 struct ib_ucq_object
*uobj
;
814 struct ib_uverbs_event_file
*ev_file
;
818 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
821 memset(&resp
, 0, sizeof resp
);
823 mutex_lock(&ib_uverbs_idr_mutex
);
825 cq
= idr_find(&ib_uverbs_cq_idr
, cmd
.cq_handle
);
826 if (!cq
|| cq
->uobject
->context
!= file
->ucontext
)
829 user_handle
= cq
->uobject
->user_handle
;
830 uobj
= container_of(cq
->uobject
, struct ib_ucq_object
, uobject
);
831 ev_file
= cq
->cq_context
;
833 ret
= ib_destroy_cq(cq
);
837 idr_remove(&ib_uverbs_cq_idr
, cmd
.cq_handle
);
839 mutex_lock(&file
->mutex
);
840 list_del(&uobj
->uobject
.list
);
841 mutex_unlock(&file
->mutex
);
843 ib_uverbs_release_ucq(file
, ev_file
, uobj
);
845 resp
.comp_events_reported
= uobj
->comp_events_reported
;
846 resp
.async_events_reported
= uobj
->async_events_reported
;
850 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
855 mutex_unlock(&ib_uverbs_idr_mutex
);
857 return ret
? ret
: in_len
;
860 ssize_t
ib_uverbs_create_qp(struct ib_uverbs_file
*file
,
861 const char __user
*buf
, int in_len
,
864 struct ib_uverbs_create_qp cmd
;
865 struct ib_uverbs_create_qp_resp resp
;
866 struct ib_udata udata
;
867 struct ib_uqp_object
*uobj
;
869 struct ib_cq
*scq
, *rcq
;
872 struct ib_qp_init_attr attr
;
875 if (out_len
< sizeof resp
)
878 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
881 INIT_UDATA(&udata
, buf
+ sizeof cmd
,
882 (unsigned long) cmd
.response
+ sizeof resp
,
883 in_len
- sizeof cmd
, out_len
- sizeof resp
);
885 uobj
= kmalloc(sizeof *uobj
, GFP_KERNEL
);
889 mutex_lock(&ib_uverbs_idr_mutex
);
891 pd
= idr_find(&ib_uverbs_pd_idr
, cmd
.pd_handle
);
892 scq
= idr_find(&ib_uverbs_cq_idr
, cmd
.send_cq_handle
);
893 rcq
= idr_find(&ib_uverbs_cq_idr
, cmd
.recv_cq_handle
);
894 srq
= cmd
.is_srq
? idr_find(&ib_uverbs_srq_idr
, cmd
.srq_handle
) : NULL
;
896 if (!pd
|| pd
->uobject
->context
!= file
->ucontext
||
897 !scq
|| scq
->uobject
->context
!= file
->ucontext
||
898 !rcq
|| rcq
->uobject
->context
!= file
->ucontext
||
899 (cmd
.is_srq
&& (!srq
|| srq
->uobject
->context
!= file
->ucontext
))) {
904 attr
.event_handler
= ib_uverbs_qp_event_handler
;
905 attr
.qp_context
= file
;
909 attr
.sq_sig_type
= cmd
.sq_sig_all
? IB_SIGNAL_ALL_WR
: IB_SIGNAL_REQ_WR
;
910 attr
.qp_type
= cmd
.qp_type
;
912 attr
.cap
.max_send_wr
= cmd
.max_send_wr
;
913 attr
.cap
.max_recv_wr
= cmd
.max_recv_wr
;
914 attr
.cap
.max_send_sge
= cmd
.max_send_sge
;
915 attr
.cap
.max_recv_sge
= cmd
.max_recv_sge
;
916 attr
.cap
.max_inline_data
= cmd
.max_inline_data
;
918 uobj
->uevent
.uobject
.user_handle
= cmd
.user_handle
;
919 uobj
->uevent
.uobject
.context
= file
->ucontext
;
920 uobj
->uevent
.events_reported
= 0;
921 INIT_LIST_HEAD(&uobj
->uevent
.event_list
);
922 INIT_LIST_HEAD(&uobj
->mcast_list
);
924 qp
= pd
->device
->create_qp(pd
, &attr
, &udata
);
930 qp
->device
= pd
->device
;
932 qp
->send_cq
= attr
.send_cq
;
933 qp
->recv_cq
= attr
.recv_cq
;
935 qp
->uobject
= &uobj
->uevent
.uobject
;
936 qp
->event_handler
= attr
.event_handler
;
937 qp
->qp_context
= attr
.qp_context
;
938 qp
->qp_type
= attr
.qp_type
;
939 atomic_inc(&pd
->usecnt
);
940 atomic_inc(&attr
.send_cq
->usecnt
);
941 atomic_inc(&attr
.recv_cq
->usecnt
);
943 atomic_inc(&attr
.srq
->usecnt
);
945 memset(&resp
, 0, sizeof resp
);
946 resp
.qpn
= qp
->qp_num
;
949 if (!idr_pre_get(&ib_uverbs_qp_idr
, GFP_KERNEL
)) {
954 ret
= idr_get_new(&ib_uverbs_qp_idr
, qp
, &uobj
->uevent
.uobject
.id
);
961 resp
.qp_handle
= uobj
->uevent
.uobject
.id
;
962 resp
.max_recv_sge
= attr
.cap
.max_recv_sge
;
963 resp
.max_send_sge
= attr
.cap
.max_send_sge
;
964 resp
.max_recv_wr
= attr
.cap
.max_recv_wr
;
965 resp
.max_send_wr
= attr
.cap
.max_send_wr
;
966 resp
.max_inline_data
= attr
.cap
.max_inline_data
;
968 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
969 &resp
, sizeof resp
)) {
974 mutex_lock(&file
->mutex
);
975 list_add_tail(&uobj
->uevent
.uobject
.list
, &file
->ucontext
->qp_list
);
976 mutex_unlock(&file
->mutex
);
978 mutex_unlock(&ib_uverbs_idr_mutex
);
983 idr_remove(&ib_uverbs_qp_idr
, uobj
->uevent
.uobject
.id
);
987 atomic_dec(&pd
->usecnt
);
988 atomic_dec(&attr
.send_cq
->usecnt
);
989 atomic_dec(&attr
.recv_cq
->usecnt
);
991 atomic_dec(&attr
.srq
->usecnt
);
994 mutex_unlock(&ib_uverbs_idr_mutex
);
1000 ssize_t
ib_uverbs_query_qp(struct ib_uverbs_file
*file
,
1001 const char __user
*buf
, int in_len
,
1004 struct ib_uverbs_query_qp cmd
;
1005 struct ib_uverbs_query_qp_resp resp
;
1007 struct ib_qp_attr
*attr
;
1008 struct ib_qp_init_attr
*init_attr
;
1011 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1014 attr
= kmalloc(sizeof *attr
, GFP_KERNEL
);
1015 init_attr
= kmalloc(sizeof *init_attr
, GFP_KERNEL
);
1016 if (!attr
|| !init_attr
) {
1021 mutex_lock(&ib_uverbs_idr_mutex
);
1023 qp
= idr_find(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1024 if (qp
&& qp
->uobject
->context
== file
->ucontext
)
1025 ret
= ib_query_qp(qp
, attr
, cmd
.attr_mask
, init_attr
);
1029 mutex_unlock(&ib_uverbs_idr_mutex
);
1034 memset(&resp
, 0, sizeof resp
);
1036 resp
.qp_state
= attr
->qp_state
;
1037 resp
.cur_qp_state
= attr
->cur_qp_state
;
1038 resp
.path_mtu
= attr
->path_mtu
;
1039 resp
.path_mig_state
= attr
->path_mig_state
;
1040 resp
.qkey
= attr
->qkey
;
1041 resp
.rq_psn
= attr
->rq_psn
;
1042 resp
.sq_psn
= attr
->sq_psn
;
1043 resp
.dest_qp_num
= attr
->dest_qp_num
;
1044 resp
.qp_access_flags
= attr
->qp_access_flags
;
1045 resp
.pkey_index
= attr
->pkey_index
;
1046 resp
.alt_pkey_index
= attr
->alt_pkey_index
;
1047 resp
.en_sqd_async_notify
= attr
->en_sqd_async_notify
;
1048 resp
.max_rd_atomic
= attr
->max_rd_atomic
;
1049 resp
.max_dest_rd_atomic
= attr
->max_dest_rd_atomic
;
1050 resp
.min_rnr_timer
= attr
->min_rnr_timer
;
1051 resp
.port_num
= attr
->port_num
;
1052 resp
.timeout
= attr
->timeout
;
1053 resp
.retry_cnt
= attr
->retry_cnt
;
1054 resp
.rnr_retry
= attr
->rnr_retry
;
1055 resp
.alt_port_num
= attr
->alt_port_num
;
1056 resp
.alt_timeout
= attr
->alt_timeout
;
1058 memcpy(resp
.dest
.dgid
, attr
->ah_attr
.grh
.dgid
.raw
, 16);
1059 resp
.dest
.flow_label
= attr
->ah_attr
.grh
.flow_label
;
1060 resp
.dest
.sgid_index
= attr
->ah_attr
.grh
.sgid_index
;
1061 resp
.dest
.hop_limit
= attr
->ah_attr
.grh
.hop_limit
;
1062 resp
.dest
.traffic_class
= attr
->ah_attr
.grh
.traffic_class
;
1063 resp
.dest
.dlid
= attr
->ah_attr
.dlid
;
1064 resp
.dest
.sl
= attr
->ah_attr
.sl
;
1065 resp
.dest
.src_path_bits
= attr
->ah_attr
.src_path_bits
;
1066 resp
.dest
.static_rate
= attr
->ah_attr
.static_rate
;
1067 resp
.dest
.is_global
= !!(attr
->ah_attr
.ah_flags
& IB_AH_GRH
);
1068 resp
.dest
.port_num
= attr
->ah_attr
.port_num
;
1070 memcpy(resp
.alt_dest
.dgid
, attr
->alt_ah_attr
.grh
.dgid
.raw
, 16);
1071 resp
.alt_dest
.flow_label
= attr
->alt_ah_attr
.grh
.flow_label
;
1072 resp
.alt_dest
.sgid_index
= attr
->alt_ah_attr
.grh
.sgid_index
;
1073 resp
.alt_dest
.hop_limit
= attr
->alt_ah_attr
.grh
.hop_limit
;
1074 resp
.alt_dest
.traffic_class
= attr
->alt_ah_attr
.grh
.traffic_class
;
1075 resp
.alt_dest
.dlid
= attr
->alt_ah_attr
.dlid
;
1076 resp
.alt_dest
.sl
= attr
->alt_ah_attr
.sl
;
1077 resp
.alt_dest
.src_path_bits
= attr
->alt_ah_attr
.src_path_bits
;
1078 resp
.alt_dest
.static_rate
= attr
->alt_ah_attr
.static_rate
;
1079 resp
.alt_dest
.is_global
= !!(attr
->alt_ah_attr
.ah_flags
& IB_AH_GRH
);
1080 resp
.alt_dest
.port_num
= attr
->alt_ah_attr
.port_num
;
1082 resp
.max_send_wr
= init_attr
->cap
.max_send_wr
;
1083 resp
.max_recv_wr
= init_attr
->cap
.max_recv_wr
;
1084 resp
.max_send_sge
= init_attr
->cap
.max_send_sge
;
1085 resp
.max_recv_sge
= init_attr
->cap
.max_recv_sge
;
1086 resp
.max_inline_data
= init_attr
->cap
.max_inline_data
;
1087 resp
.sq_sig_all
= init_attr
->sq_sig_type
== IB_SIGNAL_ALL_WR
;
1089 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1090 &resp
, sizeof resp
))
1097 return ret
? ret
: in_len
;
1100 ssize_t
ib_uverbs_modify_qp(struct ib_uverbs_file
*file
,
1101 const char __user
*buf
, int in_len
,
1104 struct ib_uverbs_modify_qp cmd
;
1106 struct ib_qp_attr
*attr
;
1109 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1112 attr
= kmalloc(sizeof *attr
, GFP_KERNEL
);
1116 mutex_lock(&ib_uverbs_idr_mutex
);
1118 qp
= idr_find(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1119 if (!qp
|| qp
->uobject
->context
!= file
->ucontext
) {
1124 attr
->qp_state
= cmd
.qp_state
;
1125 attr
->cur_qp_state
= cmd
.cur_qp_state
;
1126 attr
->path_mtu
= cmd
.path_mtu
;
1127 attr
->path_mig_state
= cmd
.path_mig_state
;
1128 attr
->qkey
= cmd
.qkey
;
1129 attr
->rq_psn
= cmd
.rq_psn
;
1130 attr
->sq_psn
= cmd
.sq_psn
;
1131 attr
->dest_qp_num
= cmd
.dest_qp_num
;
1132 attr
->qp_access_flags
= cmd
.qp_access_flags
;
1133 attr
->pkey_index
= cmd
.pkey_index
;
1134 attr
->alt_pkey_index
= cmd
.alt_pkey_index
;
1135 attr
->en_sqd_async_notify
= cmd
.en_sqd_async_notify
;
1136 attr
->max_rd_atomic
= cmd
.max_rd_atomic
;
1137 attr
->max_dest_rd_atomic
= cmd
.max_dest_rd_atomic
;
1138 attr
->min_rnr_timer
= cmd
.min_rnr_timer
;
1139 attr
->port_num
= cmd
.port_num
;
1140 attr
->timeout
= cmd
.timeout
;
1141 attr
->retry_cnt
= cmd
.retry_cnt
;
1142 attr
->rnr_retry
= cmd
.rnr_retry
;
1143 attr
->alt_port_num
= cmd
.alt_port_num
;
1144 attr
->alt_timeout
= cmd
.alt_timeout
;
1146 memcpy(attr
->ah_attr
.grh
.dgid
.raw
, cmd
.dest
.dgid
, 16);
1147 attr
->ah_attr
.grh
.flow_label
= cmd
.dest
.flow_label
;
1148 attr
->ah_attr
.grh
.sgid_index
= cmd
.dest
.sgid_index
;
1149 attr
->ah_attr
.grh
.hop_limit
= cmd
.dest
.hop_limit
;
1150 attr
->ah_attr
.grh
.traffic_class
= cmd
.dest
.traffic_class
;
1151 attr
->ah_attr
.dlid
= cmd
.dest
.dlid
;
1152 attr
->ah_attr
.sl
= cmd
.dest
.sl
;
1153 attr
->ah_attr
.src_path_bits
= cmd
.dest
.src_path_bits
;
1154 attr
->ah_attr
.static_rate
= cmd
.dest
.static_rate
;
1155 attr
->ah_attr
.ah_flags
= cmd
.dest
.is_global
? IB_AH_GRH
: 0;
1156 attr
->ah_attr
.port_num
= cmd
.dest
.port_num
;
1158 memcpy(attr
->alt_ah_attr
.grh
.dgid
.raw
, cmd
.alt_dest
.dgid
, 16);
1159 attr
->alt_ah_attr
.grh
.flow_label
= cmd
.alt_dest
.flow_label
;
1160 attr
->alt_ah_attr
.grh
.sgid_index
= cmd
.alt_dest
.sgid_index
;
1161 attr
->alt_ah_attr
.grh
.hop_limit
= cmd
.alt_dest
.hop_limit
;
1162 attr
->alt_ah_attr
.grh
.traffic_class
= cmd
.alt_dest
.traffic_class
;
1163 attr
->alt_ah_attr
.dlid
= cmd
.alt_dest
.dlid
;
1164 attr
->alt_ah_attr
.sl
= cmd
.alt_dest
.sl
;
1165 attr
->alt_ah_attr
.src_path_bits
= cmd
.alt_dest
.src_path_bits
;
1166 attr
->alt_ah_attr
.static_rate
= cmd
.alt_dest
.static_rate
;
1167 attr
->alt_ah_attr
.ah_flags
= cmd
.alt_dest
.is_global
? IB_AH_GRH
: 0;
1168 attr
->alt_ah_attr
.port_num
= cmd
.alt_dest
.port_num
;
1170 ret
= ib_modify_qp(qp
, attr
, cmd
.attr_mask
);
1177 mutex_unlock(&ib_uverbs_idr_mutex
);
1183 ssize_t
ib_uverbs_destroy_qp(struct ib_uverbs_file
*file
,
1184 const char __user
*buf
, int in_len
,
1187 struct ib_uverbs_destroy_qp cmd
;
1188 struct ib_uverbs_destroy_qp_resp resp
;
1190 struct ib_uqp_object
*uobj
;
1193 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1196 memset(&resp
, 0, sizeof resp
);
1198 mutex_lock(&ib_uverbs_idr_mutex
);
1200 qp
= idr_find(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1201 if (!qp
|| qp
->uobject
->context
!= file
->ucontext
)
1204 uobj
= container_of(qp
->uobject
, struct ib_uqp_object
, uevent
.uobject
);
1206 if (!list_empty(&uobj
->mcast_list
)) {
1211 ret
= ib_destroy_qp(qp
);
1215 idr_remove(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1217 mutex_lock(&file
->mutex
);
1218 list_del(&uobj
->uevent
.uobject
.list
);
1219 mutex_unlock(&file
->mutex
);
1221 ib_uverbs_release_uevent(file
, &uobj
->uevent
);
1223 resp
.events_reported
= uobj
->uevent
.events_reported
;
1227 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1228 &resp
, sizeof resp
))
1232 mutex_unlock(&ib_uverbs_idr_mutex
);
1234 return ret
? ret
: in_len
;
1237 ssize_t
ib_uverbs_post_send(struct ib_uverbs_file
*file
,
1238 const char __user
*buf
, int in_len
,
1241 struct ib_uverbs_post_send cmd
;
1242 struct ib_uverbs_post_send_resp resp
;
1243 struct ib_uverbs_send_wr
*user_wr
;
1244 struct ib_send_wr
*wr
= NULL
, *last
, *next
, *bad_wr
;
1247 ssize_t ret
= -EINVAL
;
1249 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1252 if (in_len
< sizeof cmd
+ cmd
.wqe_size
* cmd
.wr_count
+
1253 cmd
.sge_count
* sizeof (struct ib_uverbs_sge
))
1256 if (cmd
.wqe_size
< sizeof (struct ib_uverbs_send_wr
))
1259 user_wr
= kmalloc(cmd
.wqe_size
, GFP_KERNEL
);
1263 mutex_lock(&ib_uverbs_idr_mutex
);
1265 qp
= idr_find(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1266 if (!qp
|| qp
->uobject
->context
!= file
->ucontext
)
1271 for (i
= 0; i
< cmd
.wr_count
; ++i
) {
1272 if (copy_from_user(user_wr
,
1273 buf
+ sizeof cmd
+ i
* cmd
.wqe_size
,
1279 if (user_wr
->num_sge
+ sg_ind
> cmd
.sge_count
) {
1284 next
= kmalloc(ALIGN(sizeof *next
, sizeof (struct ib_sge
)) +
1285 user_wr
->num_sge
* sizeof (struct ib_sge
),
1299 next
->wr_id
= user_wr
->wr_id
;
1300 next
->num_sge
= user_wr
->num_sge
;
1301 next
->opcode
= user_wr
->opcode
;
1302 next
->send_flags
= user_wr
->send_flags
;
1303 next
->imm_data
= (__be32 __force
) user_wr
->imm_data
;
1305 if (qp
->qp_type
== IB_QPT_UD
) {
1306 next
->wr
.ud
.ah
= idr_find(&ib_uverbs_ah_idr
,
1308 if (!next
->wr
.ud
.ah
) {
1312 next
->wr
.ud
.remote_qpn
= user_wr
->wr
.ud
.remote_qpn
;
1313 next
->wr
.ud
.remote_qkey
= user_wr
->wr
.ud
.remote_qkey
;
1315 switch (next
->opcode
) {
1316 case IB_WR_RDMA_WRITE
:
1317 case IB_WR_RDMA_WRITE_WITH_IMM
:
1318 case IB_WR_RDMA_READ
:
1319 next
->wr
.rdma
.remote_addr
=
1320 user_wr
->wr
.rdma
.remote_addr
;
1321 next
->wr
.rdma
.rkey
=
1322 user_wr
->wr
.rdma
.rkey
;
1324 case IB_WR_ATOMIC_CMP_AND_SWP
:
1325 case IB_WR_ATOMIC_FETCH_AND_ADD
:
1326 next
->wr
.atomic
.remote_addr
=
1327 user_wr
->wr
.atomic
.remote_addr
;
1328 next
->wr
.atomic
.compare_add
=
1329 user_wr
->wr
.atomic
.compare_add
;
1330 next
->wr
.atomic
.swap
= user_wr
->wr
.atomic
.swap
;
1331 next
->wr
.atomic
.rkey
= user_wr
->wr
.atomic
.rkey
;
1338 if (next
->num_sge
) {
1339 next
->sg_list
= (void *) next
+
1340 ALIGN(sizeof *next
, sizeof (struct ib_sge
));
1341 if (copy_from_user(next
->sg_list
,
1343 cmd
.wr_count
* cmd
.wqe_size
+
1344 sg_ind
* sizeof (struct ib_sge
),
1345 next
->num_sge
* sizeof (struct ib_sge
))) {
1349 sg_ind
+= next
->num_sge
;
1351 next
->sg_list
= NULL
;
1355 ret
= qp
->device
->post_send(qp
, wr
, &bad_wr
);
1357 for (next
= wr
; next
; next
= next
->next
) {
1363 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1364 &resp
, sizeof resp
))
1368 mutex_unlock(&ib_uverbs_idr_mutex
);
1378 return ret
? ret
: in_len
;
1381 static struct ib_recv_wr
*ib_uverbs_unmarshall_recv(const char __user
*buf
,
1387 struct ib_uverbs_recv_wr
*user_wr
;
1388 struct ib_recv_wr
*wr
= NULL
, *last
, *next
;
1393 if (in_len
< wqe_size
* wr_count
+
1394 sge_count
* sizeof (struct ib_uverbs_sge
))
1395 return ERR_PTR(-EINVAL
);
1397 if (wqe_size
< sizeof (struct ib_uverbs_recv_wr
))
1398 return ERR_PTR(-EINVAL
);
1400 user_wr
= kmalloc(wqe_size
, GFP_KERNEL
);
1402 return ERR_PTR(-ENOMEM
);
1406 for (i
= 0; i
< wr_count
; ++i
) {
1407 if (copy_from_user(user_wr
, buf
+ i
* wqe_size
,
1413 if (user_wr
->num_sge
+ sg_ind
> sge_count
) {
1418 next
= kmalloc(ALIGN(sizeof *next
, sizeof (struct ib_sge
)) +
1419 user_wr
->num_sge
* sizeof (struct ib_sge
),
1433 next
->wr_id
= user_wr
->wr_id
;
1434 next
->num_sge
= user_wr
->num_sge
;
1436 if (next
->num_sge
) {
1437 next
->sg_list
= (void *) next
+
1438 ALIGN(sizeof *next
, sizeof (struct ib_sge
));
1439 if (copy_from_user(next
->sg_list
,
1440 buf
+ wr_count
* wqe_size
+
1441 sg_ind
* sizeof (struct ib_sge
),
1442 next
->num_sge
* sizeof (struct ib_sge
))) {
1446 sg_ind
+= next
->num_sge
;
1448 next
->sg_list
= NULL
;
1463 return ERR_PTR(ret
);
1466 ssize_t
ib_uverbs_post_recv(struct ib_uverbs_file
*file
,
1467 const char __user
*buf
, int in_len
,
1470 struct ib_uverbs_post_recv cmd
;
1471 struct ib_uverbs_post_recv_resp resp
;
1472 struct ib_recv_wr
*wr
, *next
, *bad_wr
;
1474 ssize_t ret
= -EINVAL
;
1476 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1479 wr
= ib_uverbs_unmarshall_recv(buf
+ sizeof cmd
,
1480 in_len
- sizeof cmd
, cmd
.wr_count
,
1481 cmd
.sge_count
, cmd
.wqe_size
);
1485 mutex_lock(&ib_uverbs_idr_mutex
);
1487 qp
= idr_find(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1488 if (!qp
|| qp
->uobject
->context
!= file
->ucontext
)
1492 ret
= qp
->device
->post_recv(qp
, wr
, &bad_wr
);
1494 for (next
= wr
; next
; next
= next
->next
) {
1501 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1502 &resp
, sizeof resp
))
1506 mutex_unlock(&ib_uverbs_idr_mutex
);
1514 return ret
? ret
: in_len
;
1517 ssize_t
ib_uverbs_post_srq_recv(struct ib_uverbs_file
*file
,
1518 const char __user
*buf
, int in_len
,
1521 struct ib_uverbs_post_srq_recv cmd
;
1522 struct ib_uverbs_post_srq_recv_resp resp
;
1523 struct ib_recv_wr
*wr
, *next
, *bad_wr
;
1525 ssize_t ret
= -EINVAL
;
1527 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1530 wr
= ib_uverbs_unmarshall_recv(buf
+ sizeof cmd
,
1531 in_len
- sizeof cmd
, cmd
.wr_count
,
1532 cmd
.sge_count
, cmd
.wqe_size
);
1536 mutex_lock(&ib_uverbs_idr_mutex
);
1538 srq
= idr_find(&ib_uverbs_srq_idr
, cmd
.srq_handle
);
1539 if (!srq
|| srq
->uobject
->context
!= file
->ucontext
)
1543 ret
= srq
->device
->post_srq_recv(srq
, wr
, &bad_wr
);
1545 for (next
= wr
; next
; next
= next
->next
) {
1552 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1553 &resp
, sizeof resp
))
1557 mutex_unlock(&ib_uverbs_idr_mutex
);
1565 return ret
? ret
: in_len
;
1568 ssize_t
ib_uverbs_create_ah(struct ib_uverbs_file
*file
,
1569 const char __user
*buf
, int in_len
,
1572 struct ib_uverbs_create_ah cmd
;
1573 struct ib_uverbs_create_ah_resp resp
;
1574 struct ib_uobject
*uobj
;
1577 struct ib_ah_attr attr
;
1580 if (out_len
< sizeof resp
)
1583 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1586 uobj
= kmalloc(sizeof *uobj
, GFP_KERNEL
);
1590 mutex_lock(&ib_uverbs_idr_mutex
);
1592 pd
= idr_find(&ib_uverbs_pd_idr
, cmd
.pd_handle
);
1593 if (!pd
|| pd
->uobject
->context
!= file
->ucontext
) {
1598 uobj
->user_handle
= cmd
.user_handle
;
1599 uobj
->context
= file
->ucontext
;
1601 attr
.dlid
= cmd
.attr
.dlid
;
1602 attr
.sl
= cmd
.attr
.sl
;
1603 attr
.src_path_bits
= cmd
.attr
.src_path_bits
;
1604 attr
.static_rate
= cmd
.attr
.static_rate
;
1605 attr
.ah_flags
= cmd
.attr
.is_global
? IB_AH_GRH
: 0;
1606 attr
.port_num
= cmd
.attr
.port_num
;
1607 attr
.grh
.flow_label
= cmd
.attr
.grh
.flow_label
;
1608 attr
.grh
.sgid_index
= cmd
.attr
.grh
.sgid_index
;
1609 attr
.grh
.hop_limit
= cmd
.attr
.grh
.hop_limit
;
1610 attr
.grh
.traffic_class
= cmd
.attr
.grh
.traffic_class
;
1611 memcpy(attr
.grh
.dgid
.raw
, cmd
.attr
.grh
.dgid
, 16);
1613 ah
= ib_create_ah(pd
, &attr
);
1622 if (!idr_pre_get(&ib_uverbs_ah_idr
, GFP_KERNEL
)) {
1627 ret
= idr_get_new(&ib_uverbs_ah_idr
, ah
, &uobj
->id
);
1634 resp
.ah_handle
= uobj
->id
;
1636 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1637 &resp
, sizeof resp
)) {
1642 mutex_lock(&file
->mutex
);
1643 list_add_tail(&uobj
->list
, &file
->ucontext
->ah_list
);
1644 mutex_unlock(&file
->mutex
);
1646 mutex_unlock(&ib_uverbs_idr_mutex
);
1651 idr_remove(&ib_uverbs_ah_idr
, uobj
->id
);
1657 mutex_unlock(&ib_uverbs_idr_mutex
);
1663 ssize_t
ib_uverbs_destroy_ah(struct ib_uverbs_file
*file
,
1664 const char __user
*buf
, int in_len
, int out_len
)
1666 struct ib_uverbs_destroy_ah cmd
;
1668 struct ib_uobject
*uobj
;
1671 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1674 mutex_lock(&ib_uverbs_idr_mutex
);
1676 ah
= idr_find(&ib_uverbs_ah_idr
, cmd
.ah_handle
);
1677 if (!ah
|| ah
->uobject
->context
!= file
->ucontext
)
1682 ret
= ib_destroy_ah(ah
);
1686 idr_remove(&ib_uverbs_ah_idr
, cmd
.ah_handle
);
1688 mutex_lock(&file
->mutex
);
1689 list_del(&uobj
->list
);
1690 mutex_unlock(&file
->mutex
);
1695 mutex_unlock(&ib_uverbs_idr_mutex
);
1697 return ret
? ret
: in_len
;
1700 ssize_t
ib_uverbs_attach_mcast(struct ib_uverbs_file
*file
,
1701 const char __user
*buf
, int in_len
,
1704 struct ib_uverbs_attach_mcast cmd
;
1706 struct ib_uqp_object
*uobj
;
1707 struct ib_uverbs_mcast_entry
*mcast
;
1710 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1713 mutex_lock(&ib_uverbs_idr_mutex
);
1715 qp
= idr_find(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1716 if (!qp
|| qp
->uobject
->context
!= file
->ucontext
)
1719 uobj
= container_of(qp
->uobject
, struct ib_uqp_object
, uevent
.uobject
);
1721 list_for_each_entry(mcast
, &uobj
->mcast_list
, list
)
1722 if (cmd
.mlid
== mcast
->lid
&&
1723 !memcmp(cmd
.gid
, mcast
->gid
.raw
, sizeof mcast
->gid
.raw
)) {
1728 mcast
= kmalloc(sizeof *mcast
, GFP_KERNEL
);
1734 mcast
->lid
= cmd
.mlid
;
1735 memcpy(mcast
->gid
.raw
, cmd
.gid
, sizeof mcast
->gid
.raw
);
1737 ret
= ib_attach_mcast(qp
, &mcast
->gid
, cmd
.mlid
);
1739 uobj
= container_of(qp
->uobject
, struct ib_uqp_object
,
1741 list_add_tail(&mcast
->list
, &uobj
->mcast_list
);
1746 mutex_unlock(&ib_uverbs_idr_mutex
);
1748 return ret
? ret
: in_len
;
1751 ssize_t
ib_uverbs_detach_mcast(struct ib_uverbs_file
*file
,
1752 const char __user
*buf
, int in_len
,
1755 struct ib_uverbs_detach_mcast cmd
;
1756 struct ib_uqp_object
*uobj
;
1758 struct ib_uverbs_mcast_entry
*mcast
;
1761 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1764 mutex_lock(&ib_uverbs_idr_mutex
);
1766 qp
= idr_find(&ib_uverbs_qp_idr
, cmd
.qp_handle
);
1767 if (!qp
|| qp
->uobject
->context
!= file
->ucontext
)
1770 ret
= ib_detach_mcast(qp
, (union ib_gid
*) cmd
.gid
, cmd
.mlid
);
1774 uobj
= container_of(qp
->uobject
, struct ib_uqp_object
, uevent
.uobject
);
1776 list_for_each_entry(mcast
, &uobj
->mcast_list
, list
)
1777 if (cmd
.mlid
== mcast
->lid
&&
1778 !memcmp(cmd
.gid
, mcast
->gid
.raw
, sizeof mcast
->gid
.raw
)) {
1779 list_del(&mcast
->list
);
1785 mutex_unlock(&ib_uverbs_idr_mutex
);
1787 return ret
? ret
: in_len
;
1790 ssize_t
ib_uverbs_create_srq(struct ib_uverbs_file
*file
,
1791 const char __user
*buf
, int in_len
,
1794 struct ib_uverbs_create_srq cmd
;
1795 struct ib_uverbs_create_srq_resp resp
;
1796 struct ib_udata udata
;
1797 struct ib_uevent_object
*uobj
;
1800 struct ib_srq_init_attr attr
;
1803 if (out_len
< sizeof resp
)
1806 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1809 INIT_UDATA(&udata
, buf
+ sizeof cmd
,
1810 (unsigned long) cmd
.response
+ sizeof resp
,
1811 in_len
- sizeof cmd
, out_len
- sizeof resp
);
1813 uobj
= kmalloc(sizeof *uobj
, GFP_KERNEL
);
1817 mutex_lock(&ib_uverbs_idr_mutex
);
1819 pd
= idr_find(&ib_uverbs_pd_idr
, cmd
.pd_handle
);
1821 if (!pd
|| pd
->uobject
->context
!= file
->ucontext
) {
1826 attr
.event_handler
= ib_uverbs_srq_event_handler
;
1827 attr
.srq_context
= file
;
1828 attr
.attr
.max_wr
= cmd
.max_wr
;
1829 attr
.attr
.max_sge
= cmd
.max_sge
;
1830 attr
.attr
.srq_limit
= cmd
.srq_limit
;
1832 uobj
->uobject
.user_handle
= cmd
.user_handle
;
1833 uobj
->uobject
.context
= file
->ucontext
;
1834 uobj
->events_reported
= 0;
1835 INIT_LIST_HEAD(&uobj
->event_list
);
1837 srq
= pd
->device
->create_srq(pd
, &attr
, &udata
);
1843 srq
->device
= pd
->device
;
1845 srq
->uobject
= &uobj
->uobject
;
1846 srq
->event_handler
= attr
.event_handler
;
1847 srq
->srq_context
= attr
.srq_context
;
1848 atomic_inc(&pd
->usecnt
);
1849 atomic_set(&srq
->usecnt
, 0);
1851 memset(&resp
, 0, sizeof resp
);
1854 if (!idr_pre_get(&ib_uverbs_srq_idr
, GFP_KERNEL
)) {
1859 ret
= idr_get_new(&ib_uverbs_srq_idr
, srq
, &uobj
->uobject
.id
);
1866 resp
.srq_handle
= uobj
->uobject
.id
;
1867 resp
.max_wr
= attr
.attr
.max_wr
;
1868 resp
.max_sge
= attr
.attr
.max_sge
;
1870 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1871 &resp
, sizeof resp
)) {
1876 mutex_lock(&file
->mutex
);
1877 list_add_tail(&uobj
->uobject
.list
, &file
->ucontext
->srq_list
);
1878 mutex_unlock(&file
->mutex
);
1880 mutex_unlock(&ib_uverbs_idr_mutex
);
1885 idr_remove(&ib_uverbs_srq_idr
, uobj
->uobject
.id
);
1888 ib_destroy_srq(srq
);
1889 atomic_dec(&pd
->usecnt
);
1892 mutex_unlock(&ib_uverbs_idr_mutex
);
1898 ssize_t
ib_uverbs_modify_srq(struct ib_uverbs_file
*file
,
1899 const char __user
*buf
, int in_len
,
1902 struct ib_uverbs_modify_srq cmd
;
1904 struct ib_srq_attr attr
;
1907 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1910 mutex_lock(&ib_uverbs_idr_mutex
);
1912 srq
= idr_find(&ib_uverbs_srq_idr
, cmd
.srq_handle
);
1913 if (!srq
|| srq
->uobject
->context
!= file
->ucontext
) {
1918 attr
.max_wr
= cmd
.max_wr
;
1919 attr
.srq_limit
= cmd
.srq_limit
;
1921 ret
= ib_modify_srq(srq
, &attr
, cmd
.attr_mask
);
1924 mutex_unlock(&ib_uverbs_idr_mutex
);
1926 return ret
? ret
: in_len
;
1929 ssize_t
ib_uverbs_query_srq(struct ib_uverbs_file
*file
,
1930 const char __user
*buf
,
1931 int in_len
, int out_len
)
1933 struct ib_uverbs_query_srq cmd
;
1934 struct ib_uverbs_query_srq_resp resp
;
1935 struct ib_srq_attr attr
;
1939 if (out_len
< sizeof resp
)
1942 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1945 mutex_lock(&ib_uverbs_idr_mutex
);
1947 srq
= idr_find(&ib_uverbs_srq_idr
, cmd
.srq_handle
);
1948 if (srq
&& srq
->uobject
->context
== file
->ucontext
)
1949 ret
= ib_query_srq(srq
, &attr
);
1953 mutex_unlock(&ib_uverbs_idr_mutex
);
1958 memset(&resp
, 0, sizeof resp
);
1960 resp
.max_wr
= attr
.max_wr
;
1961 resp
.max_sge
= attr
.max_sge
;
1962 resp
.srq_limit
= attr
.srq_limit
;
1964 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
1965 &resp
, sizeof resp
))
1969 return ret
? ret
: in_len
;
1972 ssize_t
ib_uverbs_destroy_srq(struct ib_uverbs_file
*file
,
1973 const char __user
*buf
, int in_len
,
1976 struct ib_uverbs_destroy_srq cmd
;
1977 struct ib_uverbs_destroy_srq_resp resp
;
1979 struct ib_uevent_object
*uobj
;
1982 if (copy_from_user(&cmd
, buf
, sizeof cmd
))
1985 mutex_lock(&ib_uverbs_idr_mutex
);
1987 memset(&resp
, 0, sizeof resp
);
1989 srq
= idr_find(&ib_uverbs_srq_idr
, cmd
.srq_handle
);
1990 if (!srq
|| srq
->uobject
->context
!= file
->ucontext
)
1993 uobj
= container_of(srq
->uobject
, struct ib_uevent_object
, uobject
);
1995 ret
= ib_destroy_srq(srq
);
1999 idr_remove(&ib_uverbs_srq_idr
, cmd
.srq_handle
);
2001 mutex_lock(&file
->mutex
);
2002 list_del(&uobj
->uobject
.list
);
2003 mutex_unlock(&file
->mutex
);
2005 ib_uverbs_release_uevent(file
, uobj
);
2007 resp
.events_reported
= uobj
->events_reported
;
2011 if (copy_to_user((void __user
*) (unsigned long) cmd
.response
,
2012 &resp
, sizeof resp
))
2016 mutex_unlock(&ib_uverbs_idr_mutex
);
2018 return ret
? ret
: in_len
;