38 #include <linux/slab.h>
40 #include <asm/uaccess.h>
57 #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
59 (udata)->inbuf = (void __user *) (ibuf); \
60 (udata)->outbuf = (void __user *) (obuf); \
61 (udata)->inlen = (ilen); \
62 (udata)->outlen = (olen); \
90 static void init_uobj(
struct ib_uobject *uobj,
u64 user_handle,
95 kref_init(&uobj->
ref);
101 static void release_uobj(
struct kref *
kref)
108 kref_put(&uobj->
ref, release_uobj);
111 static void put_uobj_read(
struct ib_uobject *uobj)
117 static void put_uobj_write(
struct ib_uobject *uobj)
131 spin_lock(&ib_uverbs_idr_lock);
133 spin_unlock(&ib_uverbs_idr_lock);
148 static struct ib_uobject *__idr_get_uobj(
struct idr *idr,
int id,
153 spin_lock(&ib_uverbs_idr_lock);
157 kref_get(&uobj->
ref);
161 spin_unlock(&ib_uverbs_idr_lock);
166 static struct ib_uobject *idr_read_uobj(
struct idr *idr,
int id,
171 uobj = __idr_get_uobj(idr,
id, context);
187 static struct ib_uobject *idr_write_uobj(
struct idr *idr,
int id,
192 uobj = __idr_get_uobj(idr,
id, context);
198 put_uobj_write(uobj);
205 static void *idr_read_obj(
struct idr *idr,
int id,
struct ib_ucontext *context,
210 uobj = idr_read_uobj(idr,
id, context, nested);
214 static struct ib_pd *idr_read_pd(
int pd_handle,
struct ib_ucontext *context)
216 return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context, 0);
219 static void put_pd_read(
struct ib_pd *pd)
226 return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context, nested);
229 static void put_cq_read(
struct ib_cq *cq)
234 static struct ib_ah *idr_read_ah(
int ah_handle,
struct ib_ucontext *context)
236 return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context, 0);
239 static void put_ah_read(
struct ib_ah *
ah)
246 return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0);
253 uobj = idr_write_uobj(&ib_uverbs_qp_idr, qp_handle, context);
257 static void put_qp_read(
struct ib_qp *qp)
262 static void put_qp_write(
struct ib_qp *qp)
269 return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0);
272 static void put_srq_read(
struct ib_srq *srq)
280 *uobj = idr_read_uobj(&ib_uverbs_xrcd_idr, xrcd_handle, context, 0);
284 static void put_xrcd_read(
struct ib_uobject *uobj)
290 const char __user *
buf,
301 if (out_len <
sizeof resp)
315 (
unsigned long) cmd.
response +
sizeof resp,
316 in_len -
sizeof cmd, out_len -
sizeof resp);
319 if (IS_ERR(ucontext)) {
320 ret = PTR_ERR(ucontext);
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);
349 &resp,
sizeof resp)) {
363 kref_get(&file->
ref);
387 const char __user *
buf,
395 if (out_len <
sizeof resp)
405 memset(&resp, 0,
sizeof resp);
456 const char __user *
buf,
464 if (out_len <
sizeof resp)
474 memset(&resp, 0,
sizeof resp);
506 const char __user *
buf,
516 if (out_len <
sizeof resp)
523 (
unsigned long) cmd.
response +
sizeof resp,
524 in_len -
sizeof cmd, out_len -
sizeof resp);
530 init_uobj(uobj, 0, file->
ucontext, &pd_lock_class);
533 pd = file->
device->ib_dev->alloc_pd(file->
device->ib_dev,
549 memset(&resp, 0,
sizeof resp);
553 &resp,
sizeof resp)) {
575 put_uobj_write(uobj);
580 const char __user *
buf,
598 put_uobj_write(uobj);
641 }
else if (inode > scan->
inode) {
649 rb_link_node(&entry->
node, parent, p);
666 else if (inode > entry->
inode)
679 entry = xrcd_table_search(dev, inode);
691 entry = xrcd_table_search(dev, inode);
709 struct inode *inode =
NULL;
713 if (out_len <
sizeof resp)
720 (
unsigned long) cmd.
response +
sizeof resp,
721 in_len -
sizeof cmd, out_len -
sizeof resp);
730 goto err_tree_mutex_unlock;
733 inode = f.
file->f_path.dentry->d_inode;
734 xrcd = find_xrcd(file->
device, inode);
738 goto err_tree_mutex_unlock;
743 goto err_tree_mutex_unlock;
750 goto err_tree_mutex_unlock;
758 xrcd = file->
device->ib_dev->alloc_xrcd(file->
device->ib_dev,
779 memset(&resp, 0,
sizeof resp);
785 ret = xrcd_table_insert(file->
device, inode, xrcd);
787 goto err_insert_xrcd;
793 &resp,
sizeof resp)) {
814 xrcd_table_delete(file->
device, inode);
827 err_tree_mutex_unlock:
843 struct inode *inode =
NULL;
862 put_uobj_write(uobj);
877 put_uobj_write(uobj);
883 xrcd_table_delete(file->
device, inode);
910 xrcd_table_delete(dev, inode);
925 if (out_len <
sizeof resp)
932 (
unsigned long) cmd.
response +
sizeof resp,
933 in_len -
sizeof cmd, out_len -
sizeof resp);
950 init_uobj(uobj, 0, file->
ucontext, &mr_lock_class);
977 memset(&resp, 0,
sizeof resp);
983 &resp,
sizeof resp)) {
1010 put_uobj_write(uobj);
1036 put_uobj_write(uobj);
1061 if (out_len <
sizeof resp)
1075 return PTR_ERR(filp);
1079 &resp,
sizeof resp)) {
1101 if (out_len <
sizeof resp)
1108 (
unsigned long) cmd.
response +
sizeof resp,
1109 in_len -
sizeof cmd, out_len -
sizeof resp);
1155 memset(&resp, 0,
sizeof resp);
1160 &resp,
sizeof resp)) {
1186 put_uobj_write(&obj->
uobject);
1204 (
unsigned long) cmd.
response +
sizeof resp,
1205 in_len -
sizeof cmd, out_len -
sizeof resp);
1211 ret = cq->
device->resize_cq(cq, cmd.
cqe, &udata);
1218 &resp,
sizeof resp.
cqe))
1224 return ret ? ret :
in_len;
1227 static int copy_wc_to_user(
void __user *
dest,
struct ib_wc *
wc)
1237 tmp.qp_num = wc->
qp->qp_num;
1274 data_ptr = header_ptr +
sizeof resp;
1276 memset(&resp, 0,
sizeof resp);
1277 while (resp.count < cmd.
ne) {
1278 ret = ib_poll_cq(cq, 1, &wc);
1284 ret = copy_wc_to_user(data_ptr, &wc);
1352 put_uobj_write(uobj);
1365 memset(&resp, 0,
sizeof resp);
1372 &resp,
sizeof resp))
1396 if (out_len <
sizeof resp)
1406 (
unsigned long) cmd.
response +
sizeof resp,
1407 in_len -
sizeof cmd, out_len -
sizeof resp);
1471 obj->
uevent.events_reported = 0;
1472 INIT_LIST_HEAD(&obj->
uevent.event_list);
1478 qp = device->
create_qp(pd, &attr, &udata);
1505 obj->
uevent.uobject.object = qp;
1510 memset(&resp, 0,
sizeof resp);
1520 &resp,
sizeof resp)) {
1526 put_xrcd_read(xrcd_uobj);
1531 if (rcq && rcq != scq)
1540 obj->
uevent.uobject.live = 1;
1554 put_xrcd_read(xrcd_uobj);
1559 if (rcq && rcq != scq)
1564 put_uobj_write(&obj->
uevent.uobject);
1581 if (out_len <
sizeof resp)
1588 (
unsigned long) cmd.
response +
sizeof resp,
1589 in_len -
sizeof cmd, out_len -
sizeof resp);
1609 obj->
uevent.events_reported = 0;
1610 INIT_LIST_HEAD(&obj->
uevent.event_list);
1621 obj->
uevent.uobject.object = qp;
1626 memset(&resp, 0,
sizeof resp);
1631 &resp,
sizeof resp)) {
1636 put_xrcd_read(xrcd_uobj);
1642 obj->
uevent.uobject.live = 1;
1655 put_xrcd_read(xrcd_uobj);
1656 put_uobj_write(&obj->
uevent.uobject);
1676 if (!attr || !init_attr) {
1694 memset(&resp, 0,
sizeof resp);
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;
1725 resp.
dest.src_path_bits = attr->
ah_attr.src_path_bits;
1726 resp.
dest.static_rate = attr->
ah_attr.static_rate;
1750 &resp,
sizeof resp))
1757 return ret ? ret :
in_len;
1823 attr->
ah_attr.grh.flow_label = cmd.
dest.flow_label;
1824 attr->
ah_attr.grh.sgid_index = cmd.
dest.sgid_index;
1826 attr->
ah_attr.grh.traffic_class = cmd.
dest.traffic_class;
1829 attr->
ah_attr.src_path_bits = cmd.
dest.src_path_bits;
1847 ret = qp->
device->modify_qp(qp, attr,
1880 memset(&resp, 0,
sizeof resp);
1889 put_uobj_write(uobj);
1897 put_uobj_write(uobj);
1915 &resp,
sizeof resp))
1957 buf +
sizeof cmd + i * cmd.
wqe_size,
1983 next->wr_id = user_wr->
wr_id;
1984 next->num_sge = user_wr->
num_sge;
1985 next->opcode = user_wr->
opcode;
1989 next->wr.ud.ah = idr_read_ah(user_wr->
wr.
ud.ah,
1991 if (!next->wr.ud.ah) {
1995 next->wr.ud.remote_qpn = user_wr->
wr.
ud.remote_qpn;
1996 next->wr.ud.remote_qkey = user_wr->
wr.
ud.remote_qkey;
1998 switch (next->opcode) {
2004 next->wr.rdma.remote_addr =
2005 user_wr->
wr.
rdma.remote_addr;
2006 next->wr.rdma.rkey =
2014 next->ex.invalidate_rkey =
2019 next->wr.atomic.remote_addr =
2021 next->wr.atomic.compare_add =
2023 next->wr.atomic.swap = user_wr->
wr.
atomic.swap;
2024 next->wr.atomic.rkey = user_wr->
wr.
atomic.rkey;
2031 if (next->num_sge) {
2032 next->sg_list = (
void *) next +
2038 next->num_sge *
sizeof (
struct ib_sge))) {
2042 sg_ind += next->num_sge;
2044 next->sg_list =
NULL;
2050 for (next = wr;
next; next = next->next) {
2057 &resp,
sizeof resp))
2064 if (is_ud && wr->
wr.
ud.ah)
2065 put_ah_read(wr->
wr.
ud.ah);
2074 return ret ? ret :
in_len;
2077 static struct ib_recv_wr *ib_uverbs_unmarshall_recv(
const char __user *
buf,
2089 if (in_len < wqe_size * wr_count +
2109 if (user_wr->
num_sge + sg_ind > sge_count) {
2129 next->wr_id = user_wr->
wr_id;
2130 next->num_sge = user_wr->
num_sge;
2132 if (next->num_sge) {
2133 next->sg_list = (
void *) next +
2136 buf + wr_count * wqe_size +
2142 sg_ind += next->num_sge;
2144 next->sg_list =
NULL;
2159 return ERR_PTR(ret);
2163 const char __user *buf,
int in_len,
2175 wr = ib_uverbs_unmarshall_recv(buf +
sizeof cmd,
2191 for (next = wr;
next; next = next->
next) {
2198 &resp,
sizeof resp))
2208 return ret ? ret :
in_len;
2212 const char __user *buf,
int in_len,
2224 wr = ib_uverbs_unmarshall_recv(buf +
sizeof cmd,
2235 ret = srq->
device->post_srq_recv(srq, wr, &bad_wr);
2240 for (next = wr;
next; next = next->
next) {
2247 &resp,
sizeof resp))
2257 return ret ? ret :
in_len;
2261 const char __user *buf,
int in_len,
2272 if (out_len <
sizeof resp)
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;
2319 &resp,
sizeof resp)) {
2346 put_uobj_write(uobj);
2351 const char __user *buf,
int in_len,
int out_len)
2370 put_uobj_write(uobj);
2387 const char __user *buf,
int in_len,
2430 return ret ? ret :
in_len;
2434 const char __user *buf,
int in_len,
2467 return ret ? ret :
in_len;
2491 if (!
attr.ext.xrc.xrcd) {
2500 if (!
attr.ext.xrc.cq) {
2519 obj->
uevent.events_reported = 0;
2520 INIT_LIST_HEAD(&obj->
uevent.event_list);
2522 srq = pd->
device->create_srq(pd, &
attr, udata);
2545 obj->
uevent.uobject.object = srq;
2546 ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->
uevent.uobject);
2564 put_uobj_read(xrcd_uobj);
2565 put_cq_read(
attr.ext.xrc.cq);
2573 obj->
uevent.uobject.live = 1;
2590 put_cq_read(
attr.ext.xrc.cq);
2595 put_uobj_read(xrcd_uobj);
2599 put_uobj_write(&obj->
uevent.uobject);
2604 const char __user *buf,
int in_len,
2613 if (out_len <
sizeof resp)
2628 (
unsigned long) cmd.
response +
sizeof resp,
2629 in_len -
sizeof cmd, out_len -
sizeof resp);
2631 ret = __uverbs_create_xsrq(file, &xcmd, &udata);
2639 const char __user *buf,
int in_len,
int out_len)
2646 if (out_len <
sizeof resp)
2653 (
unsigned long) cmd.
response +
sizeof resp,
2654 in_len -
sizeof cmd, out_len -
sizeof resp);
2656 ret = __uverbs_create_xsrq(file, &cmd, &udata);
2664 const char __user *buf,
int in_len,
2690 return ret ? ret :
in_len;
2694 const char __user *buf,
2703 if (out_len <
sizeof resp)
2720 memset(&resp, 0,
sizeof resp);
2727 &resp,
sizeof resp))
2734 const char __user *buf,
int in_len,
2757 put_uobj_write(uobj);
2770 memset(&resp, 0,
sizeof resp);
2776 &resp,
sizeof resp))
2779 return ret ? ret :
in_len;