1 /* 2 * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33 #include <linux/completion.h> 34 #include <linux/file.h> 35 #include <linux/mutex.h> 36 #include <linux/poll.h> 37 #include <linux/sched.h> 38 #include <linux/idr.h> 39 #include <linux/in.h> 40 #include <linux/in6.h> 41 #include <linux/miscdevice.h> 42 #include <linux/slab.h> 43 #include <linux/sysctl.h> 44 #include <linux/module.h> 45 46 #include <rdma/rdma_user_cm.h> 47 #include <rdma/ib_marshall.h> 48 #include <rdma/rdma_cm.h> 49 #include <rdma/rdma_cm_ib.h> 50 51 MODULE_AUTHOR("Sean Hefty"); 52 MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); 53 MODULE_LICENSE("Dual BSD/GPL"); 54 55 static unsigned int max_backlog = 1024; 56 57 static struct ctl_table_header *ucma_ctl_table_hdr; 58 static ctl_table ucma_ctl_table[] = { 59 { 60 .procname = "max_backlog", 61 .data = &max_backlog, 62 .maxlen = sizeof max_backlog, 63 .mode = 0644, 64 .proc_handler = proc_dointvec, 65 }, 66 { } 67 }; 68 69 struct ucma_file { 70 struct mutex mut; 71 struct file *filp; 72 struct list_head ctx_list; 73 struct list_head event_list; 74 wait_queue_head_t poll_wait; 75 }; 76 77 struct ucma_context { 78 int id; 79 struct completion comp; 80 atomic_t ref; 81 int events_reported; 82 int backlog; 83 84 struct ucma_file *file; 85 struct rdma_cm_id *cm_id; 86 u64 uid; 87 88 struct list_head list; 89 struct list_head mc_list; 90 }; 91 92 struct ucma_multicast { 93 struct ucma_context *ctx; 94 int id; 95 int events_reported; 96 97 u64 uid; 98 struct list_head list; 99 struct sockaddr_storage addr; 100 }; 101 102 struct ucma_event { 103 struct ucma_context *ctx; 104 struct ucma_multicast *mc; 105 struct list_head list; 106 struct rdma_cm_id *cm_id; 107 struct rdma_ucm_event_resp resp; 108 }; 109 110 static DEFINE_MUTEX(mut); 111 static DEFINE_IDR(ctx_idr); 112 static DEFINE_IDR(multicast_idr); 113 114 static inline struct ucma_context *_ucma_find_context(int id, 115 struct ucma_file *file) 116 { 117 struct ucma_context *ctx; 118 119 ctx = idr_find(&ctx_idr, id); 120 if (!ctx) 121 ctx = ERR_PTR(-ENOENT); 122 else if (ctx->file != file) 123 ctx = ERR_PTR(-EINVAL); 124 return ctx; 125 } 126 127 static struct ucma_context *ucma_get_ctx(struct ucma_file *file, int id) 128 { 129 struct ucma_context *ctx; 130 131 mutex_lock(&mut); 132 ctx = _ucma_find_context(id, file); 133 if (!IS_ERR(ctx)) 134 atomic_inc(&ctx->ref); 135 mutex_unlock(&mut); 136 return ctx; 137 } 138 139 static void ucma_put_ctx(struct ucma_context *ctx) 140 { 141 if (atomic_dec_and_test(&ctx->ref)) 142 complete(&ctx->comp); 143 } 144 145 static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file) 146 { 147 struct ucma_context *ctx; 148 149 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 150 if (!ctx) 151 return NULL; 152 153 atomic_set(&ctx->ref, 1); 154 init_completion(&ctx->comp); 155 INIT_LIST_HEAD(&ctx->mc_list); 156 ctx->file = file; 157 158 mutex_lock(&mut); 159 ctx->id = idr_alloc(&ctx_idr, ctx, 0, 0, GFP_KERNEL); 160 mutex_unlock(&mut); 161 if (ctx->id < 0) 162 goto error; 163 164 list_add_tail(&ctx->list, &file->ctx_list); 165 return ctx; 166 167 error: 168 kfree(ctx); 169 return NULL; 170 } 171 172 static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx) 173 { 174 struct ucma_multicast *mc; 175 176 mc = kzalloc(sizeof(*mc), GFP_KERNEL); 177 if (!mc) 178 return NULL; 179 180 mutex_lock(&mut); 181 mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL); 182 mutex_unlock(&mut); 183 if (mc->id < 0) 184 goto error; 185 186 mc->ctx = ctx; 187 list_add_tail(&mc->list, &ctx->mc_list); 188 return mc; 189 190 error: 191 kfree(mc); 192 return NULL; 193 } 194 195 static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst, 196 struct rdma_conn_param *src) 197 { 198 if (src->private_data_len) 199 memcpy(dst->private_data, src->private_data, 200 src->private_data_len); 201 dst->private_data_len = src->private_data_len; 202 dst->responder_resources =src->responder_resources; 203 dst->initiator_depth = src->initiator_depth; 204 dst->flow_control = src->flow_control; 205 dst->retry_count = src->retry_count; 206 dst->rnr_retry_count = src->rnr_retry_count; 207 dst->srq = src->srq; 208 dst->qp_num = src->qp_num; 209 } 210 211 static void ucma_copy_ud_event(struct rdma_ucm_ud_param *dst, 212 struct rdma_ud_param *src) 213 { 214 if (src->private_data_len) 215 memcpy(dst->private_data, src->private_data, 216 src->private_data_len); 217 dst->private_data_len = src->private_data_len; 218 ib_copy_ah_attr_to_user(&dst->ah_attr, &src->ah_attr); 219 dst->qp_num = src->qp_num; 220 dst->qkey = src->qkey; 221 } 222 223 static void ucma_set_event_context(struct ucma_context *ctx, 224 struct rdma_cm_event *event, 225 struct ucma_event *uevent) 226 { 227 uevent->ctx = ctx; 228 switch (event->event) { 229 case RDMA_CM_EVENT_MULTICAST_JOIN: 230 case RDMA_CM_EVENT_MULTICAST_ERROR: 231 uevent->mc = (struct ucma_multicast *) 232 event->param.ud.private_data; 233 uevent->resp.uid = uevent->mc->uid; 234 uevent->resp.id = uevent->mc->id; 235 break; 236 default: 237 uevent->resp.uid = ctx->uid; 238 uevent->resp.id = ctx->id; 239 break; 240 } 241 } 242 243 static int ucma_event_handler(struct rdma_cm_id *cm_id, 244 struct rdma_cm_event *event) 245 { 246 struct ucma_event *uevent; 247 struct ucma_context *ctx = cm_id->context; 248 int ret = 0; 249 250 uevent = kzalloc(sizeof(*uevent), GFP_KERNEL); 251 if (!uevent) 252 return event->event == RDMA_CM_EVENT_CONNECT_REQUEST; 253 254 mutex_lock(&ctx->file->mut); 255 uevent->cm_id = cm_id; 256 ucma_set_event_context(ctx, event, uevent); 257 uevent->resp.event = event->event; 258 uevent->resp.status = event->status; 259 if (cm_id->qp_type == IB_QPT_UD) 260 ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud); 261 else 262 ucma_copy_conn_event(&uevent->resp.param.conn, 263 &event->param.conn); 264 265 if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { 266 if (!ctx->backlog) { 267 ret = -ENOMEM; 268 kfree(uevent); 269 goto out; 270 } 271 ctx->backlog--; 272 } else if (!ctx->uid) { 273 /* 274 * We ignore events for new connections until userspace has set 275 * their context. This can only happen if an error occurs on a 276 * new connection before the user accepts it. This is okay, 277 * since the accept will just fail later. 278 */ 279 kfree(uevent); 280 goto out; 281 } 282 283 list_add_tail(&uevent->list, &ctx->file->event_list); 284 wake_up_interruptible(&ctx->file->poll_wait); 285 out: 286 mutex_unlock(&ctx->file->mut); 287 return ret; 288 } 289 290 static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf, 291 int in_len, int out_len) 292 { 293 struct ucma_context *ctx; 294 struct rdma_ucm_get_event cmd; 295 struct ucma_event *uevent; 296 int ret = 0; 297 298 if (out_len < sizeof uevent->resp) 299 return -ENOSPC; 300 301 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 302 return -EFAULT; 303 304 mutex_lock(&file->mut); 305 while (list_empty(&file->event_list)) { 306 mutex_unlock(&file->mut); 307 308 if (file->filp->f_flags & O_NONBLOCK) 309 return -EAGAIN; 310 311 if (wait_event_interruptible(file->poll_wait, 312 !list_empty(&file->event_list))) 313 return -ERESTARTSYS; 314 315 mutex_lock(&file->mut); 316 } 317 318 uevent = list_entry(file->event_list.next, struct ucma_event, list); 319 320 if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST) { 321 ctx = ucma_alloc_ctx(file); 322 if (!ctx) { 323 ret = -ENOMEM; 324 goto done; 325 } 326 uevent->ctx->backlog++; 327 ctx->cm_id = uevent->cm_id; 328 ctx->cm_id->context = ctx; 329 uevent->resp.id = ctx->id; 330 } 331 332 if (copy_to_user((void __user *)(unsigned long)cmd.response, 333 &uevent->resp, sizeof uevent->resp)) { 334 ret = -EFAULT; 335 goto done; 336 } 337 338 list_del(&uevent->list); 339 uevent->ctx->events_reported++; 340 if (uevent->mc) 341 uevent->mc->events_reported++; 342 kfree(uevent); 343 done: 344 mutex_unlock(&file->mut); 345 return ret; 346 } 347 348 static int ucma_get_qp_type(struct rdma_ucm_create_id *cmd, enum ib_qp_type *qp_type) 349 { 350 switch (cmd->ps) { 351 case RDMA_PS_TCP: 352 *qp_type = IB_QPT_RC; 353 return 0; 354 case RDMA_PS_UDP: 355 case RDMA_PS_IPOIB: 356 *qp_type = IB_QPT_UD; 357 return 0; 358 case RDMA_PS_IB: 359 *qp_type = cmd->qp_type; 360 return 0; 361 default: 362 return -EINVAL; 363 } 364 } 365 366 static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, 367 int in_len, int out_len) 368 { 369 struct rdma_ucm_create_id cmd; 370 struct rdma_ucm_create_id_resp resp; 371 struct ucma_context *ctx; 372 enum ib_qp_type qp_type; 373 int ret; 374 375 if (out_len < sizeof(resp)) 376 return -ENOSPC; 377 378 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 379 return -EFAULT; 380 381 ret = ucma_get_qp_type(&cmd, &qp_type); 382 if (ret) 383 return ret; 384 385 mutex_lock(&file->mut); 386 ctx = ucma_alloc_ctx(file); 387 mutex_unlock(&file->mut); 388 if (!ctx) 389 return -ENOMEM; 390 391 ctx->uid = cmd.uid; 392 ctx->cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps, qp_type); 393 if (IS_ERR(ctx->cm_id)) { 394 ret = PTR_ERR(ctx->cm_id); 395 goto err1; 396 } 397 398 resp.id = ctx->id; 399 if (copy_to_user((void __user *)(unsigned long)cmd.response, 400 &resp, sizeof(resp))) { 401 ret = -EFAULT; 402 goto err2; 403 } 404 return 0; 405 406 err2: 407 rdma_destroy_id(ctx->cm_id); 408 err1: 409 mutex_lock(&mut); 410 idr_remove(&ctx_idr, ctx->id); 411 mutex_unlock(&mut); 412 kfree(ctx); 413 return ret; 414 } 415 416 static void ucma_cleanup_multicast(struct ucma_context *ctx) 417 { 418 struct ucma_multicast *mc, *tmp; 419 420 mutex_lock(&mut); 421 list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) { 422 list_del(&mc->list); 423 idr_remove(&multicast_idr, mc->id); 424 kfree(mc); 425 } 426 mutex_unlock(&mut); 427 } 428 429 static void ucma_cleanup_mc_events(struct ucma_multicast *mc) 430 { 431 struct ucma_event *uevent, *tmp; 432 433 list_for_each_entry_safe(uevent, tmp, &mc->ctx->file->event_list, list) { 434 if (uevent->mc != mc) 435 continue; 436 437 list_del(&uevent->list); 438 kfree(uevent); 439 } 440 } 441 442 /* 443 * We cannot hold file->mut when calling rdma_destroy_id() or we can 444 * deadlock. We also acquire file->mut in ucma_event_handler(), and 445 * rdma_destroy_id() will wait until all callbacks have completed. 446 */ 447 static int ucma_free_ctx(struct ucma_context *ctx) 448 { 449 int events_reported; 450 struct ucma_event *uevent, *tmp; 451 LIST_HEAD(list); 452 453 /* No new events will be generated after destroying the id. */ 454 rdma_destroy_id(ctx->cm_id); 455 456 ucma_cleanup_multicast(ctx); 457 458 /* Cleanup events not yet reported to the user. */ 459 mutex_lock(&ctx->file->mut); 460 list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) { 461 if (uevent->ctx == ctx) 462 list_move_tail(&uevent->list, &list); 463 } 464 list_del(&ctx->list); 465 mutex_unlock(&ctx->file->mut); 466 467 list_for_each_entry_safe(uevent, tmp, &list, list) { 468 list_del(&uevent->list); 469 if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST) 470 rdma_destroy_id(uevent->cm_id); 471 kfree(uevent); 472 } 473 474 events_reported = ctx->events_reported; 475 kfree(ctx); 476 return events_reported; 477 } 478 479 static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, 480 int in_len, int out_len) 481 { 482 struct rdma_ucm_destroy_id cmd; 483 struct rdma_ucm_destroy_id_resp resp; 484 struct ucma_context *ctx; 485 int ret = 0; 486 487 if (out_len < sizeof(resp)) 488 return -ENOSPC; 489 490 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 491 return -EFAULT; 492 493 mutex_lock(&mut); 494 ctx = _ucma_find_context(cmd.id, file); 495 if (!IS_ERR(ctx)) 496 idr_remove(&ctx_idr, ctx->id); 497 mutex_unlock(&mut); 498 499 if (IS_ERR(ctx)) 500 return PTR_ERR(ctx); 501 502 ucma_put_ctx(ctx); 503 wait_for_completion(&ctx->comp); 504 resp.events_reported = ucma_free_ctx(ctx); 505 506 if (copy_to_user((void __user *)(unsigned long)cmd.response, 507 &resp, sizeof(resp))) 508 ret = -EFAULT; 509 510 return ret; 511 } 512 513 static ssize_t ucma_bind_addr(struct ucma_file *file, const char __user *inbuf, 514 int in_len, int out_len) 515 { 516 struct rdma_ucm_bind_addr cmd; 517 struct ucma_context *ctx; 518 int ret; 519 520 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 521 return -EFAULT; 522 523 ctx = ucma_get_ctx(file, cmd.id); 524 if (IS_ERR(ctx)) 525 return PTR_ERR(ctx); 526 527 ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr); 528 ucma_put_ctx(ctx); 529 return ret; 530 } 531 532 static ssize_t ucma_resolve_addr(struct ucma_file *file, 533 const char __user *inbuf, 534 int in_len, int out_len) 535 { 536 struct rdma_ucm_resolve_addr cmd; 537 struct ucma_context *ctx; 538 int ret; 539 540 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 541 return -EFAULT; 542 543 ctx = ucma_get_ctx(file, cmd.id); 544 if (IS_ERR(ctx)) 545 return PTR_ERR(ctx); 546 547 ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, 548 (struct sockaddr *) &cmd.dst_addr, 549 cmd.timeout_ms); 550 ucma_put_ctx(ctx); 551 return ret; 552 } 553 554 static ssize_t ucma_resolve_route(struct ucma_file *file, 555 const char __user *inbuf, 556 int in_len, int out_len) 557 { 558 struct rdma_ucm_resolve_route cmd; 559 struct ucma_context *ctx; 560 int ret; 561 562 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 563 return -EFAULT; 564 565 ctx = ucma_get_ctx(file, cmd.id); 566 if (IS_ERR(ctx)) 567 return PTR_ERR(ctx); 568 569 ret = rdma_resolve_route(ctx->cm_id, cmd.timeout_ms); 570 ucma_put_ctx(ctx); 571 return ret; 572 } 573 574 static void ucma_copy_ib_route(struct rdma_ucm_query_route_resp *resp, 575 struct rdma_route *route) 576 { 577 struct rdma_dev_addr *dev_addr; 578 579 resp->num_paths = route->num_paths; 580 switch (route->num_paths) { 581 case 0: 582 dev_addr = &route->addr.dev_addr; 583 rdma_addr_get_dgid(dev_addr, 584 (union ib_gid *) &resp->ib_route[0].dgid); 585 rdma_addr_get_sgid(dev_addr, 586 (union ib_gid *) &resp->ib_route[0].sgid); 587 resp->ib_route[0].pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr)); 588 break; 589 case 2: 590 ib_copy_path_rec_to_user(&resp->ib_route[1], 591 &route->path_rec[1]); 592 /* fall through */ 593 case 1: 594 ib_copy_path_rec_to_user(&resp->ib_route[0], 595 &route->path_rec[0]); 596 break; 597 default: 598 break; 599 } 600 } 601 602 static void ucma_copy_iboe_route(struct rdma_ucm_query_route_resp *resp, 603 struct rdma_route *route) 604 { 605 struct rdma_dev_addr *dev_addr; 606 struct net_device *dev; 607 u16 vid = 0; 608 609 resp->num_paths = route->num_paths; 610 switch (route->num_paths) { 611 case 0: 612 dev_addr = &route->addr.dev_addr; 613 dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); 614 if (dev) { 615 vid = rdma_vlan_dev_vlan_id(dev); 616 dev_put(dev); 617 } 618 619 iboe_mac_vlan_to_ll((union ib_gid *) &resp->ib_route[0].dgid, 620 dev_addr->dst_dev_addr, vid); 621 iboe_addr_get_sgid(dev_addr, 622 (union ib_gid *) &resp->ib_route[0].sgid); 623 resp->ib_route[0].pkey = cpu_to_be16(0xffff); 624 break; 625 case 2: 626 ib_copy_path_rec_to_user(&resp->ib_route[1], 627 &route->path_rec[1]); 628 /* fall through */ 629 case 1: 630 ib_copy_path_rec_to_user(&resp->ib_route[0], 631 &route->path_rec[0]); 632 break; 633 default: 634 break; 635 } 636 } 637 638 static void ucma_copy_iw_route(struct rdma_ucm_query_route_resp *resp, 639 struct rdma_route *route) 640 { 641 struct rdma_dev_addr *dev_addr; 642 643 dev_addr = &route->addr.dev_addr; 644 rdma_addr_get_dgid(dev_addr, (union ib_gid *) &resp->ib_route[0].dgid); 645 rdma_addr_get_sgid(dev_addr, (union ib_gid *) &resp->ib_route[0].sgid); 646 } 647 648 static ssize_t ucma_query_route(struct ucma_file *file, 649 const char __user *inbuf, 650 int in_len, int out_len) 651 { 652 struct rdma_ucm_query_route cmd; 653 struct rdma_ucm_query_route_resp resp; 654 struct ucma_context *ctx; 655 struct sockaddr *addr; 656 int ret = 0; 657 658 if (out_len < sizeof(resp)) 659 return -ENOSPC; 660 661 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 662 return -EFAULT; 663 664 ctx = ucma_get_ctx(file, cmd.id); 665 if (IS_ERR(ctx)) 666 return PTR_ERR(ctx); 667 668 memset(&resp, 0, sizeof resp); 669 addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr; 670 memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ? 671 sizeof(struct sockaddr_in) : 672 sizeof(struct sockaddr_in6)); 673 addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr; 674 memcpy(&resp.dst_addr, addr, addr->sa_family == AF_INET ? 675 sizeof(struct sockaddr_in) : 676 sizeof(struct sockaddr_in6)); 677 if (!ctx->cm_id->device) 678 goto out; 679 680 resp.node_guid = (__force __u64) ctx->cm_id->device->node_guid; 681 resp.port_num = ctx->cm_id->port_num; 682 switch (rdma_node_get_transport(ctx->cm_id->device->node_type)) { 683 case RDMA_TRANSPORT_IB: 684 switch (rdma_port_get_link_layer(ctx->cm_id->device, 685 ctx->cm_id->port_num)) { 686 case IB_LINK_LAYER_INFINIBAND: 687 ucma_copy_ib_route(&resp, &ctx->cm_id->route); 688 break; 689 case IB_LINK_LAYER_ETHERNET: 690 ucma_copy_iboe_route(&resp, &ctx->cm_id->route); 691 break; 692 default: 693 break; 694 } 695 break; 696 case RDMA_TRANSPORT_IWARP: 697 ucma_copy_iw_route(&resp, &ctx->cm_id->route); 698 break; 699 default: 700 break; 701 } 702 703 out: 704 if (copy_to_user((void __user *)(unsigned long)cmd.response, 705 &resp, sizeof(resp))) 706 ret = -EFAULT; 707 708 ucma_put_ctx(ctx); 709 return ret; 710 } 711 712 static void ucma_copy_conn_param(struct rdma_conn_param *dst, 713 struct rdma_ucm_conn_param *src) 714 { 715 dst->private_data = src->private_data; 716 dst->private_data_len = src->private_data_len; 717 dst->responder_resources =src->responder_resources; 718 dst->initiator_depth = src->initiator_depth; 719 dst->flow_control = src->flow_control; 720 dst->retry_count = src->retry_count; 721 dst->rnr_retry_count = src->rnr_retry_count; 722 dst->srq = src->srq; 723 dst->qp_num = src->qp_num; 724 } 725 726 static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, 727 int in_len, int out_len) 728 { 729 struct rdma_ucm_connect cmd; 730 struct rdma_conn_param conn_param; 731 struct ucma_context *ctx; 732 int ret; 733 734 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 735 return -EFAULT; 736 737 if (!cmd.conn_param.valid) 738 return -EINVAL; 739 740 ctx = ucma_get_ctx(file, cmd.id); 741 if (IS_ERR(ctx)) 742 return PTR_ERR(ctx); 743 744 ucma_copy_conn_param(&conn_param, &cmd.conn_param); 745 ret = rdma_connect(ctx->cm_id, &conn_param); 746 ucma_put_ctx(ctx); 747 return ret; 748 } 749 750 static ssize_t ucma_listen(struct ucma_file *file, const char __user *inbuf, 751 int in_len, int out_len) 752 { 753 struct rdma_ucm_listen cmd; 754 struct ucma_context *ctx; 755 int ret; 756 757 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 758 return -EFAULT; 759 760 ctx = ucma_get_ctx(file, cmd.id); 761 if (IS_ERR(ctx)) 762 return PTR_ERR(ctx); 763 764 ctx->backlog = cmd.backlog > 0 && cmd.backlog < max_backlog ? 765 cmd.backlog : max_backlog; 766 ret = rdma_listen(ctx->cm_id, ctx->backlog); 767 ucma_put_ctx(ctx); 768 return ret; 769 } 770 771 static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, 772 int in_len, int out_len) 773 { 774 struct rdma_ucm_accept cmd; 775 struct rdma_conn_param conn_param; 776 struct ucma_context *ctx; 777 int ret; 778 779 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 780 return -EFAULT; 781 782 ctx = ucma_get_ctx(file, cmd.id); 783 if (IS_ERR(ctx)) 784 return PTR_ERR(ctx); 785 786 if (cmd.conn_param.valid) { 787 ucma_copy_conn_param(&conn_param, &cmd.conn_param); 788 mutex_lock(&file->mut); 789 ret = rdma_accept(ctx->cm_id, &conn_param); 790 if (!ret) 791 ctx->uid = cmd.uid; 792 mutex_unlock(&file->mut); 793 } else 794 ret = rdma_accept(ctx->cm_id, NULL); 795 796 ucma_put_ctx(ctx); 797 return ret; 798 } 799 800 static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf, 801 int in_len, int out_len) 802 { 803 struct rdma_ucm_reject cmd; 804 struct ucma_context *ctx; 805 int ret; 806 807 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 808 return -EFAULT; 809 810 ctx = ucma_get_ctx(file, cmd.id); 811 if (IS_ERR(ctx)) 812 return PTR_ERR(ctx); 813 814 ret = rdma_reject(ctx->cm_id, cmd.private_data, cmd.private_data_len); 815 ucma_put_ctx(ctx); 816 return ret; 817 } 818 819 static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf, 820 int in_len, int out_len) 821 { 822 struct rdma_ucm_disconnect cmd; 823 struct ucma_context *ctx; 824 int ret; 825 826 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 827 return -EFAULT; 828 829 ctx = ucma_get_ctx(file, cmd.id); 830 if (IS_ERR(ctx)) 831 return PTR_ERR(ctx); 832 833 ret = rdma_disconnect(ctx->cm_id); 834 ucma_put_ctx(ctx); 835 return ret; 836 } 837 838 static ssize_t ucma_init_qp_attr(struct ucma_file *file, 839 const char __user *inbuf, 840 int in_len, int out_len) 841 { 842 struct rdma_ucm_init_qp_attr cmd; 843 struct ib_uverbs_qp_attr resp; 844 struct ucma_context *ctx; 845 struct ib_qp_attr qp_attr; 846 int ret; 847 848 if (out_len < sizeof(resp)) 849 return -ENOSPC; 850 851 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 852 return -EFAULT; 853 854 ctx = ucma_get_ctx(file, cmd.id); 855 if (IS_ERR(ctx)) 856 return PTR_ERR(ctx); 857 858 resp.qp_attr_mask = 0; 859 memset(&qp_attr, 0, sizeof qp_attr); 860 qp_attr.qp_state = cmd.qp_state; 861 ret = rdma_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask); 862 if (ret) 863 goto out; 864 865 ib_copy_qp_attr_to_user(&resp, &qp_attr); 866 if (copy_to_user((void __user *)(unsigned long)cmd.response, 867 &resp, sizeof(resp))) 868 ret = -EFAULT; 869 870 out: 871 ucma_put_ctx(ctx); 872 return ret; 873 } 874 875 static int ucma_set_option_id(struct ucma_context *ctx, int optname, 876 void *optval, size_t optlen) 877 { 878 int ret = 0; 879 880 switch (optname) { 881 case RDMA_OPTION_ID_TOS: 882 if (optlen != sizeof(u8)) { 883 ret = -EINVAL; 884 break; 885 } 886 rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); 887 break; 888 case RDMA_OPTION_ID_REUSEADDR: 889 if (optlen != sizeof(int)) { 890 ret = -EINVAL; 891 break; 892 } 893 ret = rdma_set_reuseaddr(ctx->cm_id, *((int *) optval) ? 1 : 0); 894 break; 895 case RDMA_OPTION_ID_AFONLY: 896 if (optlen != sizeof(int)) { 897 ret = -EINVAL; 898 break; 899 } 900 ret = rdma_set_afonly(ctx->cm_id, *((int *) optval) ? 1 : 0); 901 break; 902 default: 903 ret = -ENOSYS; 904 } 905 906 return ret; 907 } 908 909 static int ucma_set_ib_path(struct ucma_context *ctx, 910 struct ib_path_rec_data *path_data, size_t optlen) 911 { 912 struct ib_sa_path_rec sa_path; 913 struct rdma_cm_event event; 914 int ret; 915 916 if (optlen % sizeof(*path_data)) 917 return -EINVAL; 918 919 for (; optlen; optlen -= sizeof(*path_data), path_data++) { 920 if (path_data->flags == (IB_PATH_GMP | IB_PATH_PRIMARY | 921 IB_PATH_BIDIRECTIONAL)) 922 break; 923 } 924 925 if (!optlen) 926 return -EINVAL; 927 928 ib_sa_unpack_path(path_data->path_rec, &sa_path); 929 ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1); 930 if (ret) 931 return ret; 932 933 memset(&event, 0, sizeof event); 934 event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; 935 return ucma_event_handler(ctx->cm_id, &event); 936 } 937 938 static int ucma_set_option_ib(struct ucma_context *ctx, int optname, 939 void *optval, size_t optlen) 940 { 941 int ret; 942 943 switch (optname) { 944 case RDMA_OPTION_IB_PATH: 945 ret = ucma_set_ib_path(ctx, optval, optlen); 946 break; 947 default: 948 ret = -ENOSYS; 949 } 950 951 return ret; 952 } 953 954 static int ucma_set_option_level(struct ucma_context *ctx, int level, 955 int optname, void *optval, size_t optlen) 956 { 957 int ret; 958 959 switch (level) { 960 case RDMA_OPTION_ID: 961 ret = ucma_set_option_id(ctx, optname, optval, optlen); 962 break; 963 case RDMA_OPTION_IB: 964 ret = ucma_set_option_ib(ctx, optname, optval, optlen); 965 break; 966 default: 967 ret = -ENOSYS; 968 } 969 970 return ret; 971 } 972 973 static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, 974 int in_len, int out_len) 975 { 976 struct rdma_ucm_set_option cmd; 977 struct ucma_context *ctx; 978 void *optval; 979 int ret; 980 981 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 982 return -EFAULT; 983 984 ctx = ucma_get_ctx(file, cmd.id); 985 if (IS_ERR(ctx)) 986 return PTR_ERR(ctx); 987 988 optval = memdup_user((void __user *) (unsigned long) cmd.optval, 989 cmd.optlen); 990 if (IS_ERR(optval)) { 991 ret = PTR_ERR(optval); 992 goto out; 993 } 994 995 ret = ucma_set_option_level(ctx, cmd.level, cmd.optname, optval, 996 cmd.optlen); 997 kfree(optval); 998 999 out: 1000 ucma_put_ctx(ctx); 1001 return ret; 1002 } 1003 1004 static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, 1005 int in_len, int out_len) 1006 { 1007 struct rdma_ucm_notify cmd; 1008 struct ucma_context *ctx; 1009 int ret; 1010 1011 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 1012 return -EFAULT; 1013 1014 ctx = ucma_get_ctx(file, cmd.id); 1015 if (IS_ERR(ctx)) 1016 return PTR_ERR(ctx); 1017 1018 ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event); 1019 ucma_put_ctx(ctx); 1020 return ret; 1021 } 1022 1023 static ssize_t ucma_join_multicast(struct ucma_file *file, 1024 const char __user *inbuf, 1025 int in_len, int out_len) 1026 { 1027 struct rdma_ucm_join_mcast cmd; 1028 struct rdma_ucm_create_id_resp resp; 1029 struct ucma_context *ctx; 1030 struct ucma_multicast *mc; 1031 int ret; 1032 1033 if (out_len < sizeof(resp)) 1034 return -ENOSPC; 1035 1036 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 1037 return -EFAULT; 1038 1039 ctx = ucma_get_ctx(file, cmd.id); 1040 if (IS_ERR(ctx)) 1041 return PTR_ERR(ctx); 1042 1043 mutex_lock(&file->mut); 1044 mc = ucma_alloc_multicast(ctx); 1045 if (!mc) { 1046 ret = -ENOMEM; 1047 goto err1; 1048 } 1049 1050 mc->uid = cmd.uid; 1051 memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr); 1052 ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc); 1053 if (ret) 1054 goto err2; 1055 1056 resp.id = mc->id; 1057 if (copy_to_user((void __user *)(unsigned long)cmd.response, 1058 &resp, sizeof(resp))) { 1059 ret = -EFAULT; 1060 goto err3; 1061 } 1062 1063 mutex_unlock(&file->mut); 1064 ucma_put_ctx(ctx); 1065 return 0; 1066 1067 err3: 1068 rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr); 1069 ucma_cleanup_mc_events(mc); 1070 err2: 1071 mutex_lock(&mut); 1072 idr_remove(&multicast_idr, mc->id); 1073 mutex_unlock(&mut); 1074 list_del(&mc->list); 1075 kfree(mc); 1076 err1: 1077 mutex_unlock(&file->mut); 1078 ucma_put_ctx(ctx); 1079 return ret; 1080 } 1081 1082 static ssize_t ucma_leave_multicast(struct ucma_file *file, 1083 const char __user *inbuf, 1084 int in_len, int out_len) 1085 { 1086 struct rdma_ucm_destroy_id cmd; 1087 struct rdma_ucm_destroy_id_resp resp; 1088 struct ucma_multicast *mc; 1089 int ret = 0; 1090 1091 if (out_len < sizeof(resp)) 1092 return -ENOSPC; 1093 1094 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 1095 return -EFAULT; 1096 1097 mutex_lock(&mut); 1098 mc = idr_find(&multicast_idr, cmd.id); 1099 if (!mc) 1100 mc = ERR_PTR(-ENOENT); 1101 else if (mc->ctx->file != file) 1102 mc = ERR_PTR(-EINVAL); 1103 else { 1104 idr_remove(&multicast_idr, mc->id); 1105 atomic_inc(&mc->ctx->ref); 1106 } 1107 mutex_unlock(&mut); 1108 1109 if (IS_ERR(mc)) { 1110 ret = PTR_ERR(mc); 1111 goto out; 1112 } 1113 1114 rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr); 1115 mutex_lock(&mc->ctx->file->mut); 1116 ucma_cleanup_mc_events(mc); 1117 list_del(&mc->list); 1118 mutex_unlock(&mc->ctx->file->mut); 1119 1120 ucma_put_ctx(mc->ctx); 1121 resp.events_reported = mc->events_reported; 1122 kfree(mc); 1123 1124 if (copy_to_user((void __user *)(unsigned long)cmd.response, 1125 &resp, sizeof(resp))) 1126 ret = -EFAULT; 1127 out: 1128 return ret; 1129 } 1130 1131 static void ucma_lock_files(struct ucma_file *file1, struct ucma_file *file2) 1132 { 1133 /* Acquire mutex's based on pointer comparison to prevent deadlock. */ 1134 if (file1 < file2) { 1135 mutex_lock(&file1->mut); 1136 mutex_lock(&file2->mut); 1137 } else { 1138 mutex_lock(&file2->mut); 1139 mutex_lock(&file1->mut); 1140 } 1141 } 1142 1143 static void ucma_unlock_files(struct ucma_file *file1, struct ucma_file *file2) 1144 { 1145 if (file1 < file2) { 1146 mutex_unlock(&file2->mut); 1147 mutex_unlock(&file1->mut); 1148 } else { 1149 mutex_unlock(&file1->mut); 1150 mutex_unlock(&file2->mut); 1151 } 1152 } 1153 1154 static void ucma_move_events(struct ucma_context *ctx, struct ucma_file *file) 1155 { 1156 struct ucma_event *uevent, *tmp; 1157 1158 list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) 1159 if (uevent->ctx == ctx) 1160 list_move_tail(&uevent->list, &file->event_list); 1161 } 1162 1163 static ssize_t ucma_migrate_id(struct ucma_file *new_file, 1164 const char __user *inbuf, 1165 int in_len, int out_len) 1166 { 1167 struct rdma_ucm_migrate_id cmd; 1168 struct rdma_ucm_migrate_resp resp; 1169 struct ucma_context *ctx; 1170 struct fd f; 1171 struct ucma_file *cur_file; 1172 int ret = 0; 1173 1174 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 1175 return -EFAULT; 1176 1177 /* Get current fd to protect against it being closed */ 1178 f = fdget(cmd.fd); 1179 if (!f.file) 1180 return -ENOENT; 1181 1182 /* Validate current fd and prevent destruction of id. */ 1183 ctx = ucma_get_ctx(f.file->private_data, cmd.id); 1184 if (IS_ERR(ctx)) { 1185 ret = PTR_ERR(ctx); 1186 goto file_put; 1187 } 1188 1189 cur_file = ctx->file; 1190 if (cur_file == new_file) { 1191 resp.events_reported = ctx->events_reported; 1192 goto response; 1193 } 1194 1195 /* 1196 * Migrate events between fd's, maintaining order, and avoiding new 1197 * events being added before existing events. 1198 */ 1199 ucma_lock_files(cur_file, new_file); 1200 mutex_lock(&mut); 1201 1202 list_move_tail(&ctx->list, &new_file->ctx_list); 1203 ucma_move_events(ctx, new_file); 1204 ctx->file = new_file; 1205 resp.events_reported = ctx->events_reported; 1206 1207 mutex_unlock(&mut); 1208 ucma_unlock_files(cur_file, new_file); 1209 1210 response: 1211 if (copy_to_user((void __user *)(unsigned long)cmd.response, 1212 &resp, sizeof(resp))) 1213 ret = -EFAULT; 1214 1215 ucma_put_ctx(ctx); 1216 file_put: 1217 fdput(f); 1218 return ret; 1219 } 1220 1221 static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, 1222 const char __user *inbuf, 1223 int in_len, int out_len) = { 1224 [RDMA_USER_CM_CMD_CREATE_ID] = ucma_create_id, 1225 [RDMA_USER_CM_CMD_DESTROY_ID] = ucma_destroy_id, 1226 [RDMA_USER_CM_CMD_BIND_ADDR] = ucma_bind_addr, 1227 [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr, 1228 [RDMA_USER_CM_CMD_RESOLVE_ROUTE]= ucma_resolve_route, 1229 [RDMA_USER_CM_CMD_QUERY_ROUTE] = ucma_query_route, 1230 [RDMA_USER_CM_CMD_CONNECT] = ucma_connect, 1231 [RDMA_USER_CM_CMD_LISTEN] = ucma_listen, 1232 [RDMA_USER_CM_CMD_ACCEPT] = ucma_accept, 1233 [RDMA_USER_CM_CMD_REJECT] = ucma_reject, 1234 [RDMA_USER_CM_CMD_DISCONNECT] = ucma_disconnect, 1235 [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, 1236 [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, 1237 [RDMA_USER_CM_CMD_GET_OPTION] = NULL, 1238 [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option, 1239 [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, 1240 [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, 1241 [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, 1242 [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id 1243 }; 1244 1245 static ssize_t ucma_write(struct file *filp, const char __user *buf, 1246 size_t len, loff_t *pos) 1247 { 1248 struct ucma_file *file = filp->private_data; 1249 struct rdma_ucm_cmd_hdr hdr; 1250 ssize_t ret; 1251 1252 if (len < sizeof(hdr)) 1253 return -EINVAL; 1254 1255 if (copy_from_user(&hdr, buf, sizeof(hdr))) 1256 return -EFAULT; 1257 1258 if (hdr.cmd >= ARRAY_SIZE(ucma_cmd_table)) 1259 return -EINVAL; 1260 1261 if (hdr.in + sizeof(hdr) > len) 1262 return -EINVAL; 1263 1264 if (!ucma_cmd_table[hdr.cmd]) 1265 return -ENOSYS; 1266 1267 ret = ucma_cmd_table[hdr.cmd](file, buf + sizeof(hdr), hdr.in, hdr.out); 1268 if (!ret) 1269 ret = len; 1270 1271 return ret; 1272 } 1273 1274 static unsigned int ucma_poll(struct file *filp, struct poll_table_struct *wait) 1275 { 1276 struct ucma_file *file = filp->private_data; 1277 unsigned int mask = 0; 1278 1279 poll_wait(filp, &file->poll_wait, wait); 1280 1281 if (!list_empty(&file->event_list)) 1282 mask = POLLIN | POLLRDNORM; 1283 1284 return mask; 1285 } 1286 1287 /* 1288 * ucma_open() does not need the BKL: 1289 * 1290 * - no global state is referred to; 1291 * - there is no ioctl method to race against; 1292 * - no further module initialization is required for open to work 1293 * after the device is registered. 1294 */ 1295 static int ucma_open(struct inode *inode, struct file *filp) 1296 { 1297 struct ucma_file *file; 1298 1299 file = kmalloc(sizeof *file, GFP_KERNEL); 1300 if (!file) 1301 return -ENOMEM; 1302 1303 INIT_LIST_HEAD(&file->event_list); 1304 INIT_LIST_HEAD(&file->ctx_list); 1305 init_waitqueue_head(&file->poll_wait); 1306 mutex_init(&file->mut); 1307 1308 filp->private_data = file; 1309 file->filp = filp; 1310 1311 return nonseekable_open(inode, filp); 1312 } 1313 1314 static int ucma_close(struct inode *inode, struct file *filp) 1315 { 1316 struct ucma_file *file = filp->private_data; 1317 struct ucma_context *ctx, *tmp; 1318 1319 mutex_lock(&file->mut); 1320 list_for_each_entry_safe(ctx, tmp, &file->ctx_list, list) { 1321 mutex_unlock(&file->mut); 1322 1323 mutex_lock(&mut); 1324 idr_remove(&ctx_idr, ctx->id); 1325 mutex_unlock(&mut); 1326 1327 ucma_free_ctx(ctx); 1328 mutex_lock(&file->mut); 1329 } 1330 mutex_unlock(&file->mut); 1331 kfree(file); 1332 return 0; 1333 } 1334 1335 static const struct file_operations ucma_fops = { 1336 .owner = THIS_MODULE, 1337 .open = ucma_open, 1338 .release = ucma_close, 1339 .write = ucma_write, 1340 .poll = ucma_poll, 1341 .llseek = no_llseek, 1342 }; 1343 1344 static struct miscdevice ucma_misc = { 1345 .minor = MISC_DYNAMIC_MINOR, 1346 .name = "rdma_cm", 1347 .nodename = "infiniband/rdma_cm", 1348 .mode = 0666, 1349 .fops = &ucma_fops, 1350 }; 1351 1352 static ssize_t show_abi_version(struct device *dev, 1353 struct device_attribute *attr, 1354 char *buf) 1355 { 1356 return sprintf(buf, "%d\n", RDMA_USER_CM_ABI_VERSION); 1357 } 1358 static DEVICE_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); 1359 1360 static int __init ucma_init(void) 1361 { 1362 int ret; 1363 1364 ret = misc_register(&ucma_misc); 1365 if (ret) 1366 return ret; 1367 1368 ret = device_create_file(ucma_misc.this_device, &dev_attr_abi_version); 1369 if (ret) { 1370 printk(KERN_ERR "rdma_ucm: couldn't create abi_version attr\n"); 1371 goto err1; 1372 } 1373 1374 ucma_ctl_table_hdr = register_net_sysctl(&init_net, "net/rdma_ucm", ucma_ctl_table); 1375 if (!ucma_ctl_table_hdr) { 1376 printk(KERN_ERR "rdma_ucm: couldn't register sysctl paths\n"); 1377 ret = -ENOMEM; 1378 goto err2; 1379 } 1380 return 0; 1381 err2: 1382 device_remove_file(ucma_misc.this_device, &dev_attr_abi_version); 1383 err1: 1384 misc_deregister(&ucma_misc); 1385 return ret; 1386 } 1387 1388 static void __exit ucma_cleanup(void) 1389 { 1390 unregister_net_sysctl_table(ucma_ctl_table_hdr); 1391 device_remove_file(ucma_misc.this_device, &dev_attr_abi_version); 1392 misc_deregister(&ucma_misc); 1393 idr_destroy(&ctx_idr); 1394 } 1395 1396 module_init(ucma_init); 1397 module_exit(ucma_cleanup); 1398