1 /* 2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 3 * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. 4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 5 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 6 * Copyright (c) 2005 PathScale, Inc. All rights reserved. 7 * 8 * This software is available to you under a choice of one of two 9 * licenses. You may choose to be licensed under the terms of the GNU 10 * General Public License (GPL) Version 2, available from the file 11 * COPYING in the main directory of this source tree, or the 12 * OpenIB.org BSD license below: 13 * 14 * Redistribution and use in source and binary forms, with or 15 * without modification, are permitted provided that the following 16 * conditions are met: 17 * 18 * - Redistributions of source code must retain the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer. 21 * 22 * - Redistributions in binary form must reproduce the above 23 * copyright notice, this list of conditions and the following 24 * disclaimer in the documentation and/or other materials 25 * provided with the distribution. 26 * 27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 * SOFTWARE. 35 * 36 * $Id: uverbs_main.c 2733 2005-06-28 19:14:34Z roland $ 37 */ 38 39 #include <linux/module.h> 40 #include <linux/init.h> 41 #include <linux/device.h> 42 #include <linux/err.h> 43 #include <linux/fs.h> 44 #include <linux/poll.h> 45 #include <linux/file.h> 46 #include <linux/mount.h> 47 #include <linux/cdev.h> 48 49 #include <asm/uaccess.h> 50 51 #include "uverbs.h" 52 53 MODULE_AUTHOR("Roland Dreier"); 54 MODULE_DESCRIPTION("InfiniBand userspace verbs access"); 55 MODULE_LICENSE("Dual BSD/GPL"); 56 57 #define INFINIBANDEVENTFS_MAGIC 0x49426576 /* "IBev" */ 58 59 enum { 60 IB_UVERBS_MAJOR = 231, 61 IB_UVERBS_BASE_MINOR = 192, 62 IB_UVERBS_MAX_DEVICES = 32 63 }; 64 65 #define IB_UVERBS_BASE_DEV MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR) 66 67 static struct class *uverbs_class; 68 69 DEFINE_MUTEX(ib_uverbs_idr_mutex); 70 DEFINE_IDR(ib_uverbs_pd_idr); 71 DEFINE_IDR(ib_uverbs_mr_idr); 72 DEFINE_IDR(ib_uverbs_mw_idr); 73 DEFINE_IDR(ib_uverbs_ah_idr); 74 DEFINE_IDR(ib_uverbs_cq_idr); 75 DEFINE_IDR(ib_uverbs_qp_idr); 76 DEFINE_IDR(ib_uverbs_srq_idr); 77 78 static spinlock_t map_lock; 79 static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES]; 80 static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); 81 82 static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, 83 const char __user *buf, int in_len, 84 int out_len) = { 85 [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context, 86 [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device, 87 [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port, 88 [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, 89 [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, 90 [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, 91 [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, 92 [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel, 93 [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq, 94 [IB_USER_VERBS_CMD_RESIZE_CQ] = ib_uverbs_resize_cq, 95 [IB_USER_VERBS_CMD_POLL_CQ] = ib_uverbs_poll_cq, 96 [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq, 97 [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, 98 [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, 99 [IB_USER_VERBS_CMD_QUERY_QP] = ib_uverbs_query_qp, 100 [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, 101 [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, 102 [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send, 103 [IB_USER_VERBS_CMD_POST_RECV] = ib_uverbs_post_recv, 104 [IB_USER_VERBS_CMD_POST_SRQ_RECV] = ib_uverbs_post_srq_recv, 105 [IB_USER_VERBS_CMD_CREATE_AH] = ib_uverbs_create_ah, 106 [IB_USER_VERBS_CMD_DESTROY_AH] = ib_uverbs_destroy_ah, 107 [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, 108 [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, 109 [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, 110 [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq, 111 [IB_USER_VERBS_CMD_QUERY_SRQ] = ib_uverbs_query_srq, 112 [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, 113 }; 114 115 static struct vfsmount *uverbs_event_mnt; 116 117 static void ib_uverbs_add_one(struct ib_device *device); 118 static void ib_uverbs_remove_one(struct ib_device *device); 119 120 static void ib_uverbs_release_dev(struct kref *ref) 121 { 122 struct ib_uverbs_device *dev = 123 container_of(ref, struct ib_uverbs_device, ref); 124 125 kfree(dev); 126 } 127 128 void ib_uverbs_release_ucq(struct ib_uverbs_file *file, 129 struct ib_uverbs_event_file *ev_file, 130 struct ib_ucq_object *uobj) 131 { 132 struct ib_uverbs_event *evt, *tmp; 133 134 if (ev_file) { 135 spin_lock_irq(&ev_file->lock); 136 list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { 137 list_del(&evt->list); 138 kfree(evt); 139 } 140 spin_unlock_irq(&ev_file->lock); 141 142 kref_put(&ev_file->ref, ib_uverbs_release_event_file); 143 } 144 145 spin_lock_irq(&file->async_file->lock); 146 list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) { 147 list_del(&evt->list); 148 kfree(evt); 149 } 150 spin_unlock_irq(&file->async_file->lock); 151 } 152 153 void ib_uverbs_release_uevent(struct ib_uverbs_file *file, 154 struct ib_uevent_object *uobj) 155 { 156 struct ib_uverbs_event *evt, *tmp; 157 158 spin_lock_irq(&file->async_file->lock); 159 list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { 160 list_del(&evt->list); 161 kfree(evt); 162 } 163 spin_unlock_irq(&file->async_file->lock); 164 } 165 166 static void ib_uverbs_detach_umcast(struct ib_qp *qp, 167 struct ib_uqp_object *uobj) 168 { 169 struct ib_uverbs_mcast_entry *mcast, *tmp; 170 171 list_for_each_entry_safe(mcast, tmp, &uobj->mcast_list, list) { 172 ib_detach_mcast(qp, &mcast->gid, mcast->lid); 173 list_del(&mcast->list); 174 kfree(mcast); 175 } 176 } 177 178 static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, 179 struct ib_ucontext *context) 180 { 181 struct ib_uobject *uobj, *tmp; 182 183 if (!context) 184 return 0; 185 186 mutex_lock(&ib_uverbs_idr_mutex); 187 188 list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { 189 struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id); 190 idr_remove(&ib_uverbs_ah_idr, uobj->id); 191 ib_destroy_ah(ah); 192 list_del(&uobj->list); 193 kfree(uobj); 194 } 195 196 list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { 197 struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id); 198 struct ib_uqp_object *uqp = 199 container_of(uobj, struct ib_uqp_object, uevent.uobject); 200 idr_remove(&ib_uverbs_qp_idr, uobj->id); 201 ib_uverbs_detach_umcast(qp, uqp); 202 ib_destroy_qp(qp); 203 list_del(&uobj->list); 204 ib_uverbs_release_uevent(file, &uqp->uevent); 205 kfree(uqp); 206 } 207 208 list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) { 209 struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id); 210 struct ib_uverbs_event_file *ev_file = cq->cq_context; 211 struct ib_ucq_object *ucq = 212 container_of(uobj, struct ib_ucq_object, uobject); 213 idr_remove(&ib_uverbs_cq_idr, uobj->id); 214 ib_destroy_cq(cq); 215 list_del(&uobj->list); 216 ib_uverbs_release_ucq(file, ev_file, ucq); 217 kfree(ucq); 218 } 219 220 list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { 221 struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id); 222 struct ib_uevent_object *uevent = 223 container_of(uobj, struct ib_uevent_object, uobject); 224 idr_remove(&ib_uverbs_srq_idr, uobj->id); 225 ib_destroy_srq(srq); 226 list_del(&uobj->list); 227 ib_uverbs_release_uevent(file, uevent); 228 kfree(uevent); 229 } 230 231 /* XXX Free MWs */ 232 233 list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { 234 struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id); 235 struct ib_device *mrdev = mr->device; 236 struct ib_umem_object *memobj; 237 238 idr_remove(&ib_uverbs_mr_idr, uobj->id); 239 ib_dereg_mr(mr); 240 241 memobj = container_of(uobj, struct ib_umem_object, uobject); 242 ib_umem_release_on_close(mrdev, &memobj->umem); 243 244 list_del(&uobj->list); 245 kfree(memobj); 246 } 247 248 list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) { 249 struct ib_pd *pd = idr_find(&ib_uverbs_pd_idr, uobj->id); 250 idr_remove(&ib_uverbs_pd_idr, uobj->id); 251 ib_dealloc_pd(pd); 252 list_del(&uobj->list); 253 kfree(uobj); 254 } 255 256 mutex_unlock(&ib_uverbs_idr_mutex); 257 258 return context->device->dealloc_ucontext(context); 259 } 260 261 static void ib_uverbs_release_file(struct kref *ref) 262 { 263 struct ib_uverbs_file *file = 264 container_of(ref, struct ib_uverbs_file, ref); 265 266 module_put(file->device->ib_dev->owner); 267 kref_put(&file->device->ref, ib_uverbs_release_dev); 268 269 kfree(file); 270 } 271 272 static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf, 273 size_t count, loff_t *pos) 274 { 275 struct ib_uverbs_event_file *file = filp->private_data; 276 struct ib_uverbs_event *event; 277 int eventsz; 278 int ret = 0; 279 280 spin_lock_irq(&file->lock); 281 282 while (list_empty(&file->event_list)) { 283 spin_unlock_irq(&file->lock); 284 285 if (filp->f_flags & O_NONBLOCK) 286 return -EAGAIN; 287 288 if (wait_event_interruptible(file->poll_wait, 289 !list_empty(&file->event_list))) 290 return -ERESTARTSYS; 291 292 spin_lock_irq(&file->lock); 293 } 294 295 event = list_entry(file->event_list.next, struct ib_uverbs_event, list); 296 297 if (file->is_async) 298 eventsz = sizeof (struct ib_uverbs_async_event_desc); 299 else 300 eventsz = sizeof (struct ib_uverbs_comp_event_desc); 301 302 if (eventsz > count) { 303 ret = -EINVAL; 304 event = NULL; 305 } else { 306 list_del(file->event_list.next); 307 if (event->counter) { 308 ++(*event->counter); 309 list_del(&event->obj_list); 310 } 311 } 312 313 spin_unlock_irq(&file->lock); 314 315 if (event) { 316 if (copy_to_user(buf, event, eventsz)) 317 ret = -EFAULT; 318 else 319 ret = eventsz; 320 } 321 322 kfree(event); 323 324 return ret; 325 } 326 327 static unsigned int ib_uverbs_event_poll(struct file *filp, 328 struct poll_table_struct *wait) 329 { 330 unsigned int pollflags = 0; 331 struct ib_uverbs_event_file *file = filp->private_data; 332 333 poll_wait(filp, &file->poll_wait, wait); 334 335 spin_lock_irq(&file->lock); 336 if (!list_empty(&file->event_list)) 337 pollflags = POLLIN | POLLRDNORM; 338 spin_unlock_irq(&file->lock); 339 340 return pollflags; 341 } 342 343 void ib_uverbs_release_event_file(struct kref *ref) 344 { 345 struct ib_uverbs_event_file *file = 346 container_of(ref, struct ib_uverbs_event_file, ref); 347 348 kfree(file); 349 } 350 351 static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) 352 { 353 struct ib_uverbs_event_file *file = filp->private_data; 354 355 return fasync_helper(fd, filp, on, &file->async_queue); 356 } 357 358 static int ib_uverbs_event_close(struct inode *inode, struct file *filp) 359 { 360 struct ib_uverbs_event_file *file = filp->private_data; 361 struct ib_uverbs_event *entry, *tmp; 362 363 spin_lock_irq(&file->lock); 364 file->file = NULL; 365 list_for_each_entry_safe(entry, tmp, &file->event_list, list) { 366 if (entry->counter) 367 list_del(&entry->obj_list); 368 kfree(entry); 369 } 370 spin_unlock_irq(&file->lock); 371 372 ib_uverbs_event_fasync(-1, filp, 0); 373 374 if (file->is_async) { 375 ib_unregister_event_handler(&file->uverbs_file->event_handler); 376 kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); 377 } 378 kref_put(&file->ref, ib_uverbs_release_event_file); 379 380 return 0; 381 } 382 383 static struct file_operations uverbs_event_fops = { 384 .owner = THIS_MODULE, 385 .read = ib_uverbs_event_read, 386 .poll = ib_uverbs_event_poll, 387 .release = ib_uverbs_event_close, 388 .fasync = ib_uverbs_event_fasync 389 }; 390 391 void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) 392 { 393 struct ib_uverbs_event_file *file = cq_context; 394 struct ib_ucq_object *uobj; 395 struct ib_uverbs_event *entry; 396 unsigned long flags; 397 398 if (!file) 399 return; 400 401 spin_lock_irqsave(&file->lock, flags); 402 if (!file->file) { 403 spin_unlock_irqrestore(&file->lock, flags); 404 return; 405 } 406 407 entry = kmalloc(sizeof *entry, GFP_ATOMIC); 408 if (!entry) { 409 spin_unlock_irqrestore(&file->lock, flags); 410 return; 411 } 412 413 uobj = container_of(cq->uobject, struct ib_ucq_object, uobject); 414 415 entry->desc.comp.cq_handle = cq->uobject->user_handle; 416 entry->counter = &uobj->comp_events_reported; 417 418 list_add_tail(&entry->list, &file->event_list); 419 list_add_tail(&entry->obj_list, &uobj->comp_list); 420 spin_unlock_irqrestore(&file->lock, flags); 421 422 wake_up_interruptible(&file->poll_wait); 423 kill_fasync(&file->async_queue, SIGIO, POLL_IN); 424 } 425 426 static void ib_uverbs_async_handler(struct ib_uverbs_file *file, 427 __u64 element, __u64 event, 428 struct list_head *obj_list, 429 u32 *counter) 430 { 431 struct ib_uverbs_event *entry; 432 unsigned long flags; 433 434 spin_lock_irqsave(&file->async_file->lock, flags); 435 if (!file->async_file->file) { 436 spin_unlock_irqrestore(&file->async_file->lock, flags); 437 return; 438 } 439 440 entry = kmalloc(sizeof *entry, GFP_ATOMIC); 441 if (!entry) { 442 spin_unlock_irqrestore(&file->async_file->lock, flags); 443 return; 444 } 445 446 entry->desc.async.element = element; 447 entry->desc.async.event_type = event; 448 entry->counter = counter; 449 450 list_add_tail(&entry->list, &file->async_file->event_list); 451 if (obj_list) 452 list_add_tail(&entry->obj_list, obj_list); 453 spin_unlock_irqrestore(&file->async_file->lock, flags); 454 455 wake_up_interruptible(&file->async_file->poll_wait); 456 kill_fasync(&file->async_file->async_queue, SIGIO, POLL_IN); 457 } 458 459 void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) 460 { 461 struct ib_ucq_object *uobj = container_of(event->element.cq->uobject, 462 struct ib_ucq_object, uobject); 463 464 ib_uverbs_async_handler(uobj->uverbs_file, uobj->uobject.user_handle, 465 event->event, &uobj->async_list, 466 &uobj->async_events_reported); 467 } 468 469 void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr) 470 { 471 struct ib_uevent_object *uobj; 472 473 uobj = container_of(event->element.qp->uobject, 474 struct ib_uevent_object, uobject); 475 476 ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle, 477 event->event, &uobj->event_list, 478 &uobj->events_reported); 479 } 480 481 void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr) 482 { 483 struct ib_uevent_object *uobj; 484 485 uobj = container_of(event->element.srq->uobject, 486 struct ib_uevent_object, uobject); 487 488 ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle, 489 event->event, &uobj->event_list, 490 &uobj->events_reported); 491 } 492 493 void ib_uverbs_event_handler(struct ib_event_handler *handler, 494 struct ib_event *event) 495 { 496 struct ib_uverbs_file *file = 497 container_of(handler, struct ib_uverbs_file, event_handler); 498 499 ib_uverbs_async_handler(file, event->element.port_num, event->event, 500 NULL, NULL); 501 } 502 503 struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, 504 int is_async, int *fd) 505 { 506 struct ib_uverbs_event_file *ev_file; 507 struct file *filp; 508 int ret; 509 510 ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL); 511 if (!ev_file) 512 return ERR_PTR(-ENOMEM); 513 514 kref_init(&ev_file->ref); 515 spin_lock_init(&ev_file->lock); 516 INIT_LIST_HEAD(&ev_file->event_list); 517 init_waitqueue_head(&ev_file->poll_wait); 518 ev_file->uverbs_file = uverbs_file; 519 ev_file->async_queue = NULL; 520 ev_file->is_async = is_async; 521 522 *fd = get_unused_fd(); 523 if (*fd < 0) { 524 ret = *fd; 525 goto err; 526 } 527 528 filp = get_empty_filp(); 529 if (!filp) { 530 ret = -ENFILE; 531 goto err_fd; 532 } 533 534 ev_file->file = filp; 535 536 /* 537 * fops_get() can't fail here, because we're coming from a 538 * system call on a uverbs file, which will already have a 539 * module reference. 540 */ 541 filp->f_op = fops_get(&uverbs_event_fops); 542 filp->f_vfsmnt = mntget(uverbs_event_mnt); 543 filp->f_dentry = dget(uverbs_event_mnt->mnt_root); 544 filp->f_mapping = filp->f_dentry->d_inode->i_mapping; 545 filp->f_flags = O_RDONLY; 546 filp->f_mode = FMODE_READ; 547 filp->private_data = ev_file; 548 549 return filp; 550 551 err_fd: 552 put_unused_fd(*fd); 553 554 err: 555 kfree(ev_file); 556 return ERR_PTR(ret); 557 } 558 559 /* 560 * Look up a completion event file by FD. If lookup is successful, 561 * takes a ref to the event file struct that it returns; if 562 * unsuccessful, returns NULL. 563 */ 564 struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd) 565 { 566 struct ib_uverbs_event_file *ev_file = NULL; 567 struct file *filp; 568 569 filp = fget(fd); 570 if (!filp) 571 return NULL; 572 573 if (filp->f_op != &uverbs_event_fops) 574 goto out; 575 576 ev_file = filp->private_data; 577 if (ev_file->is_async) { 578 ev_file = NULL; 579 goto out; 580 } 581 582 kref_get(&ev_file->ref); 583 584 out: 585 fput(filp); 586 return ev_file; 587 } 588 589 static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, 590 size_t count, loff_t *pos) 591 { 592 struct ib_uverbs_file *file = filp->private_data; 593 struct ib_uverbs_cmd_hdr hdr; 594 595 if (count < sizeof hdr) 596 return -EINVAL; 597 598 if (copy_from_user(&hdr, buf, sizeof hdr)) 599 return -EFAULT; 600 601 if (hdr.in_words * 4 != count) 602 return -EINVAL; 603 604 if (hdr.command < 0 || 605 hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || 606 !uverbs_cmd_table[hdr.command] || 607 !(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command))) 608 return -EINVAL; 609 610 if (!file->ucontext && 611 hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT) 612 return -EINVAL; 613 614 return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr, 615 hdr.in_words * 4, hdr.out_words * 4); 616 } 617 618 static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) 619 { 620 struct ib_uverbs_file *file = filp->private_data; 621 622 if (!file->ucontext) 623 return -ENODEV; 624 else 625 return file->device->ib_dev->mmap(file->ucontext, vma); 626 } 627 628 static int ib_uverbs_open(struct inode *inode, struct file *filp) 629 { 630 struct ib_uverbs_device *dev; 631 struct ib_uverbs_file *file; 632 int ret; 633 634 spin_lock(&map_lock); 635 dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; 636 if (dev) 637 kref_get(&dev->ref); 638 spin_unlock(&map_lock); 639 640 if (!dev) 641 return -ENXIO; 642 643 if (!try_module_get(dev->ib_dev->owner)) { 644 ret = -ENODEV; 645 goto err; 646 } 647 648 file = kmalloc(sizeof *file, GFP_KERNEL); 649 if (!file) { 650 ret = -ENOMEM; 651 goto err_module; 652 } 653 654 file->device = dev; 655 file->ucontext = NULL; 656 file->async_file = NULL; 657 kref_init(&file->ref); 658 mutex_init(&file->mutex); 659 660 filp->private_data = file; 661 662 return 0; 663 664 err_module: 665 module_put(dev->ib_dev->owner); 666 667 err: 668 kref_put(&dev->ref, ib_uverbs_release_dev); 669 670 return ret; 671 } 672 673 static int ib_uverbs_close(struct inode *inode, struct file *filp) 674 { 675 struct ib_uverbs_file *file = filp->private_data; 676 677 ib_uverbs_cleanup_ucontext(file, file->ucontext); 678 679 if (file->async_file) 680 kref_put(&file->async_file->ref, ib_uverbs_release_event_file); 681 682 kref_put(&file->ref, ib_uverbs_release_file); 683 684 return 0; 685 } 686 687 static struct file_operations uverbs_fops = { 688 .owner = THIS_MODULE, 689 .write = ib_uverbs_write, 690 .open = ib_uverbs_open, 691 .release = ib_uverbs_close 692 }; 693 694 static struct file_operations uverbs_mmap_fops = { 695 .owner = THIS_MODULE, 696 .write = ib_uverbs_write, 697 .mmap = ib_uverbs_mmap, 698 .open = ib_uverbs_open, 699 .release = ib_uverbs_close 700 }; 701 702 static struct ib_client uverbs_client = { 703 .name = "uverbs", 704 .add = ib_uverbs_add_one, 705 .remove = ib_uverbs_remove_one 706 }; 707 708 static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 709 { 710 struct ib_uverbs_device *dev = class_get_devdata(class_dev); 711 712 if (!dev) 713 return -ENODEV; 714 715 return sprintf(buf, "%s\n", dev->ib_dev->name); 716 } 717 static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 718 719 static ssize_t show_dev_abi_version(struct class_device *class_dev, char *buf) 720 { 721 struct ib_uverbs_device *dev = class_get_devdata(class_dev); 722 723 if (!dev) 724 return -ENODEV; 725 726 return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver); 727 } 728 static CLASS_DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); 729 730 static ssize_t show_abi_version(struct class *class, char *buf) 731 { 732 return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION); 733 } 734 static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); 735 736 static void ib_uverbs_add_one(struct ib_device *device) 737 { 738 struct ib_uverbs_device *uverbs_dev; 739 740 if (!device->alloc_ucontext) 741 return; 742 743 uverbs_dev = kzalloc(sizeof *uverbs_dev, GFP_KERNEL); 744 if (!uverbs_dev) 745 return; 746 747 kref_init(&uverbs_dev->ref); 748 749 spin_lock(&map_lock); 750 uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); 751 if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) { 752 spin_unlock(&map_lock); 753 goto err; 754 } 755 set_bit(uverbs_dev->devnum, dev_map); 756 spin_unlock(&map_lock); 757 758 uverbs_dev->ib_dev = device; 759 uverbs_dev->num_comp_vectors = 1; 760 761 uverbs_dev->dev = cdev_alloc(); 762 if (!uverbs_dev->dev) 763 goto err; 764 uverbs_dev->dev->owner = THIS_MODULE; 765 uverbs_dev->dev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops; 766 kobject_set_name(&uverbs_dev->dev->kobj, "uverbs%d", uverbs_dev->devnum); 767 if (cdev_add(uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) 768 goto err_cdev; 769 770 uverbs_dev->class_dev = class_device_create(uverbs_class, NULL, 771 uverbs_dev->dev->dev, 772 device->dma_device, 773 "uverbs%d", uverbs_dev->devnum); 774 if (IS_ERR(uverbs_dev->class_dev)) 775 goto err_cdev; 776 777 class_set_devdata(uverbs_dev->class_dev, uverbs_dev); 778 779 if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_ibdev)) 780 goto err_class; 781 if (class_device_create_file(uverbs_dev->class_dev, &class_device_attr_abi_version)) 782 goto err_class; 783 784 spin_lock(&map_lock); 785 dev_table[uverbs_dev->devnum] = uverbs_dev; 786 spin_unlock(&map_lock); 787 788 ib_set_client_data(device, &uverbs_client, uverbs_dev); 789 790 return; 791 792 err_class: 793 class_device_destroy(uverbs_class, uverbs_dev->dev->dev); 794 795 err_cdev: 796 cdev_del(uverbs_dev->dev); 797 clear_bit(uverbs_dev->devnum, dev_map); 798 799 err: 800 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); 801 return; 802 } 803 804 static void ib_uverbs_remove_one(struct ib_device *device) 805 { 806 struct ib_uverbs_device *uverbs_dev = ib_get_client_data(device, &uverbs_client); 807 808 if (!uverbs_dev) 809 return; 810 811 class_set_devdata(uverbs_dev->class_dev, NULL); 812 class_device_destroy(uverbs_class, uverbs_dev->dev->dev); 813 cdev_del(uverbs_dev->dev); 814 815 spin_lock(&map_lock); 816 dev_table[uverbs_dev->devnum] = NULL; 817 spin_unlock(&map_lock); 818 819 clear_bit(uverbs_dev->devnum, dev_map); 820 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); 821 } 822 823 static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags, 824 const char *dev_name, void *data) 825 { 826 return get_sb_pseudo(fs_type, "infinibandevent:", NULL, 827 INFINIBANDEVENTFS_MAGIC); 828 } 829 830 static struct file_system_type uverbs_event_fs = { 831 /* No owner field so module can be unloaded */ 832 .name = "infinibandeventfs", 833 .get_sb = uverbs_event_get_sb, 834 .kill_sb = kill_litter_super 835 }; 836 837 static int __init ib_uverbs_init(void) 838 { 839 int ret; 840 841 spin_lock_init(&map_lock); 842 843 ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES, 844 "infiniband_verbs"); 845 if (ret) { 846 printk(KERN_ERR "user_verbs: couldn't register device number\n"); 847 goto out; 848 } 849 850 uverbs_class = class_create(THIS_MODULE, "infiniband_verbs"); 851 if (IS_ERR(uverbs_class)) { 852 ret = PTR_ERR(uverbs_class); 853 printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n"); 854 goto out_chrdev; 855 } 856 857 ret = class_create_file(uverbs_class, &class_attr_abi_version); 858 if (ret) { 859 printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n"); 860 goto out_class; 861 } 862 863 ret = register_filesystem(&uverbs_event_fs); 864 if (ret) { 865 printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n"); 866 goto out_class; 867 } 868 869 uverbs_event_mnt = kern_mount(&uverbs_event_fs); 870 if (IS_ERR(uverbs_event_mnt)) { 871 ret = PTR_ERR(uverbs_event_mnt); 872 printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n"); 873 goto out_fs; 874 } 875 876 ret = ib_register_client(&uverbs_client); 877 if (ret) { 878 printk(KERN_ERR "user_verbs: couldn't register client\n"); 879 goto out_mnt; 880 } 881 882 return 0; 883 884 out_mnt: 885 mntput(uverbs_event_mnt); 886 887 out_fs: 888 unregister_filesystem(&uverbs_event_fs); 889 890 out_class: 891 class_destroy(uverbs_class); 892 893 out_chrdev: 894 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); 895 896 out: 897 return ret; 898 } 899 900 static void __exit ib_uverbs_cleanup(void) 901 { 902 ib_unregister_client(&uverbs_client); 903 mntput(uverbs_event_mnt); 904 unregister_filesystem(&uverbs_event_fs); 905 class_destroy(uverbs_class); 906 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); 907 flush_scheduled_work(); 908 idr_destroy(&ib_uverbs_pd_idr); 909 idr_destroy(&ib_uverbs_mr_idr); 910 idr_destroy(&ib_uverbs_mw_idr); 911 idr_destroy(&ib_uverbs_ah_idr); 912 idr_destroy(&ib_uverbs_cq_idr); 913 idr_destroy(&ib_uverbs_qp_idr); 914 idr_destroy(&ib_uverbs_srq_idr); 915 } 916 917 module_init(ib_uverbs_init); 918 module_exit(ib_uverbs_cleanup); 919