1 /* 2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved. 4 * Copyright (c) 2005 PathScale, Inc. All rights reserved. 5 * Copyright (c) 2006 Mellanox Technologies. All rights reserved. 6 * 7 * This software is available to you under a choice of one of two 8 * licenses. You may choose to be licensed under the terms of the GNU 9 * General Public License (GPL) Version 2, available from the file 10 * COPYING in the main directory of this source tree, or the 11 * OpenIB.org BSD license below: 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials 24 * provided with the distribution. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 * SOFTWARE. 34 */ 35 36 #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 44 struct uverbs_lock_class { 45 struct lock_class_key key; 46 char name[16]; 47 }; 48 49 static struct uverbs_lock_class pd_lock_class = { .name = "PD-uobj" }; 50 static struct uverbs_lock_class mr_lock_class = { .name = "MR-uobj" }; 51 static struct uverbs_lock_class cq_lock_class = { .name = "CQ-uobj" }; 52 static struct uverbs_lock_class qp_lock_class = { .name = "QP-uobj" }; 53 static struct uverbs_lock_class ah_lock_class = { .name = "AH-uobj" }; 54 static struct uverbs_lock_class srq_lock_class = { .name = "SRQ-uobj" }; 55 static 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 * The ib_uobject locking scheme is as follows: 67 * 68 * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it 69 * needs to be held during all idr operations. When an object is 70 * looked up, a reference must be taken on the object's kref before 71 * dropping this lock. 72 * 73 * - Each object also has an rwsem. This rwsem must be held for 74 * reading while an operation that uses the object is performed. 75 * For example, while registering an MR, the associated PD's 76 * uobject.mutex must be held for reading. The rwsem must be held 77 * for writing while initializing or destroying an object. 78 * 79 * - In addition, each object has a "live" flag. If this flag is not 80 * set, then lookups of the object will fail even if it is found in 81 * the idr. This handles a reader that blocks and does not acquire 82 * the rwsem until after the object is destroyed. The destroy 83 * operation will set the live flag to 0 and then drop the rwsem; 84 * this will allow the reader to acquire the rwsem, see that the 85 * live flag is 0, and then drop the rwsem and its reference to 86 * object. The underlying storage will not be freed until the last 87 * reference to the object is dropped. 88 */ 89 90 static 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 101 static void release_uobj(struct kref *kref) 102 { 103 kfree(container_of(kref, struct ib_uobject, ref)); 104 } 105 106 static void put_uobj(struct ib_uobject *uobj) 107 { 108 kref_put(&uobj->ref, release_uobj); 109 } 110 111 static void put_uobj_read(struct ib_uobject *uobj) 112 { 113 up_read(&uobj->mutex); 114 put_uobj(uobj); 115 } 116 117 static void put_uobj_write(struct ib_uobject *uobj) 118 { 119 up_write(&uobj->mutex); 120 put_uobj(uobj); 121 } 122 123 static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj) 124 { 125 int ret; 126 127 retry: 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 141 void 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 148 static 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 166 static 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 187 static 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 205 static 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 214 static 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 219 static void put_pd_read(struct ib_pd *pd) 220 { 221 put_uobj_read(pd->uobject); 222 } 223 224 static 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 229 static void put_cq_read(struct ib_cq *cq) 230 { 231 put_uobj_read(cq->uobject); 232 } 233 234 static 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 239 static void put_ah_read(struct ib_ah *ah) 240 { 241 put_uobj_read(ah->uobject); 242 } 243 244 static 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 249 static 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 257 static void put_qp_read(struct ib_qp *qp) 258 { 259 put_uobj_read(qp->uobject); 260 } 261 262 static void put_qp_write(struct ib_qp *qp) 263 { 264 put_uobj_write(qp->uobject); 265 } 266 267 static 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 272 static void put_srq_read(struct ib_srq *srq) 273 { 274 put_uobj_read(srq->uobject); 275 } 276 277 static 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 284 static void put_xrcd_read(struct ib_uobject *uobj) 285 { 286 put_uobj_read(uobj); 287 } 288 289 ssize_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 372 err_file: 373 fput(filp); 374 375 err_fd: 376 put_unused_fd(resp.async_fd); 377 378 err_free: 379 ibdev->dealloc_ucontext(ucontext); 380 381 err: 382 mutex_unlock(&file->mutex); 383 return ret; 384 } 385 386 ssize_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 455 ssize_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 505 ssize_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 568 err_copy: 569 idr_remove_uobj(&ib_uverbs_pd_idr, uobj); 570 571 err_idr: 572 ib_dealloc_pd(pd); 573 574 err: 575 put_uobj_write(uobj); 576 return ret; 577 } 578 579 ssize_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 614 struct xrcd_table_entry { 615 struct rb_node node; 616 struct ib_xrcd *xrcd; 617 struct inode *inode; 618 }; 619 620 static 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 655 static 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 675 static 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 686 static 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 699 ssize_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 /* search for file descriptor */ 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 /* no file descriptor. Need CREATE flag */ 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 /* create new inode/xrcd table entry */ 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 811 err_copy: 812 if (inode) { 813 if (new_xrcd) 814 xrcd_table_delete(file->device, inode); 815 atomic_dec(&xrcd->usecnt); 816 } 817 818 err_insert_xrcd: 819 idr_remove_uobj(&ib_uverbs_xrcd_idr, &obj->uobject); 820 821 err_idr: 822 ib_dealloc_xrcd(xrcd); 823 824 err: 825 put_uobj_write(&obj->uobject); 826 827 err_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 836 ssize_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 893 out: 894 mutex_unlock(&file->device->xrcd_tree_mutex); 895 return ret; 896 } 897 898 void 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 913 ssize_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 * Local write permission is required if remote write or 940 * remote atomic permission is also requested. 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 1000 err_copy: 1001 idr_remove_uobj(&ib_uverbs_mr_idr, uobj); 1002 1003 err_unreg: 1004 ib_dereg_mr(mr); 1005 1006 err_put: 1007 put_pd_read(pd); 1008 1009 err_free: 1010 put_uobj_write(uobj); 1011 return ret; 1012 } 1013 1014 ssize_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 1052 ssize_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 1089 ssize_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 1175 err_copy: 1176 idr_remove_uobj(&ib_uverbs_cq_idr, &obj->uobject); 1177 1178 err_free: 1179 ib_destroy_cq(cq); 1180 1181 err_file: 1182 if (ev_file) 1183 ib_uverbs_release_ucq(file, ev_file, obj); 1184 1185 err: 1186 put_uobj_write(&obj->uobject); 1187 return ret; 1188 } 1189 1190 ssize_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 1221 out: 1222 put_cq_read(cq); 1223 1224 return ret ? ret : in_len; 1225 } 1226 1227 static 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 1253 ssize_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 /* we copy a struct ib_uverbs_poll_cq_resp to user space */ 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 1299 out_put: 1300 put_cq_read(cq); 1301 return ret; 1302 } 1303 1304 ssize_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 1326 ssize_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 1378 ssize_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 1546 err_copy: 1547 idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); 1548 1549 err_destroy: 1550 ib_destroy_qp(qp); 1551 1552 err_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 1568 ssize_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 1648 err_remove: 1649 idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); 1650 1651 err_destroy: 1652 ib_destroy_qp(qp); 1653 1654 err_put: 1655 put_xrcd_read(xrcd_uobj); 1656 put_uobj_write(&obj->uevent.uobject); 1657 return ret; 1658 } 1659 1660 ssize_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 1753 out: 1754 kfree(attr); 1755 kfree(init_attr); 1756 1757 return ret ? ret : in_len; 1758 } 1759 1760 /* Remove ignored fields set in the attribute mask */ 1761 static 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 1774 ssize_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 1860 out: 1861 kfree(attr); 1862 1863 return ret; 1864 } 1865 1866 ssize_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 1921 ssize_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 2060 out_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 2071 out: 2072 kfree(user_wr); 2073 2074 return ret ? ret : in_len; 2075 } 2076 2077 static 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 2150 err: 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 2162 ssize_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 2201 out: 2202 while (wr) { 2203 next = wr->next; 2204 kfree(wr); 2205 wr = next; 2206 } 2207 2208 return ret ? ret : in_len; 2209 } 2210 2211 ssize_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 2250 out: 2251 while (wr) { 2252 next = wr->next; 2253 kfree(wr); 2254 wr = next; 2255 } 2256 2257 return ret ? ret : in_len; 2258 } 2259 2260 ssize_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 2336 err_copy: 2337 idr_remove_uobj(&ib_uverbs_ah_idr, uobj); 2338 2339 err_destroy: 2340 ib_destroy_ah(ah); 2341 2342 err_put: 2343 put_pd_read(pd); 2344 2345 err: 2346 put_uobj_write(uobj); 2347 return ret; 2348 } 2349 2350 ssize_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 2386 ssize_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 2427 out_put: 2428 put_qp_write(qp); 2429 2430 return ret ? ret : in_len; 2431 } 2432 2433 ssize_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 2464 out_put: 2465 put_qp_write(qp); 2466 2467 return ret ? ret : in_len; 2468 } 2469 2470 static 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 2579 err_copy: 2580 idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject); 2581 2582 err_destroy: 2583 ib_destroy_srq(srq); 2584 2585 err_put: 2586 put_pd_read(pd); 2587 2588 err_put_cq: 2589 if (cmd->srq_type == IB_SRQT_XRC) 2590 put_cq_read(attr.ext.xrc.cq); 2591 2592 err_put_xrcd: 2593 if (cmd->srq_type == IB_SRQT_XRC) { 2594 atomic_dec(&obj->uxrcd->refcnt); 2595 put_uobj_read(xrcd_uobj); 2596 } 2597 2598 err: 2599 put_uobj_write(&obj->uevent.uobject); 2600 return ret; 2601 } 2602 2603 ssize_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 2638 ssize_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 2663 ssize_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 2693 ssize_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 2733 ssize_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