uverbs_main.c revision 273246
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 37#include <linux/module.h> 38#include <linux/device.h> 39#include <linux/err.h> 40#include <linux/fs.h> 41#include <linux/poll.h> 42#include <linux/file.h> 43#include <linux/cdev.h> 44 45#include <asm/uaccess.h> 46 47#include "uverbs.h" 48 49MODULE_AUTHOR("Roland Dreier"); 50MODULE_DESCRIPTION("InfiniBand userspace verbs access"); 51MODULE_LICENSE("Dual BSD/GPL"); 52 53#define INFINIBANDEVENTFS_MAGIC 0x49426576 /* "IBev" */ 54 55enum { 56 IB_UVERBS_MAJOR = 231, 57 IB_UVERBS_BASE_MINOR = 192, 58 IB_UVERBS_MAX_DEVICES = 32 59}; 60 61#define IB_UVERBS_BASE_DEV MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR) 62 63static struct class *uverbs_class; 64 65DEFINE_SPINLOCK(ib_uverbs_idr_lock); 66DEFINE_IDR(ib_uverbs_pd_idr); 67DEFINE_IDR(ib_uverbs_mr_idr); 68DEFINE_IDR(ib_uverbs_mw_idr); 69DEFINE_IDR(ib_uverbs_ah_idr); 70DEFINE_IDR(ib_uverbs_cq_idr); 71DEFINE_IDR(ib_uverbs_qp_idr); 72DEFINE_IDR(ib_uverbs_srq_idr); 73DEFINE_IDR(ib_uverbs_xrc_domain_idr); 74 75static spinlock_t map_lock; 76static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES]; 77static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); 78 79static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, 80 const char __user *buf, int in_len, 81 int out_len) = { 82 [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context, 83 [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device, 84 [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port, 85 [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, 86 [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, 87 [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, 88 [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, 89 [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel, 90 [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq, 91 [IB_USER_VERBS_CMD_RESIZE_CQ] = ib_uverbs_resize_cq, 92 [IB_USER_VERBS_CMD_POLL_CQ] = ib_uverbs_poll_cq, 93 [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq, 94 [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, 95 [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, 96 [IB_USER_VERBS_CMD_QUERY_QP] = ib_uverbs_query_qp, 97 [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, 98 [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, 99 [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send, 100 [IB_USER_VERBS_CMD_POST_RECV] = ib_uverbs_post_recv, 101 [IB_USER_VERBS_CMD_POST_SRQ_RECV] = ib_uverbs_post_srq_recv, 102 [IB_USER_VERBS_CMD_CREATE_AH] = ib_uverbs_create_ah, 103 [IB_USER_VERBS_CMD_DESTROY_AH] = ib_uverbs_destroy_ah, 104 [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, 105 [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, 106 [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq, 107 [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq, 108 [IB_USER_VERBS_CMD_QUERY_SRQ] = ib_uverbs_query_srq, 109 [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, 110 [IB_USER_VERBS_CMD_CREATE_XRC_SRQ] = ib_uverbs_create_xrc_srq, 111 [IB_USER_VERBS_CMD_OPEN_XRCD] = ib_uverbs_open_xrc_domain, 112 [IB_USER_VERBS_CMD_CLOSE_XRCD] = ib_uverbs_close_xrc_domain, 113 [IB_USER_VERBS_CMD_CREATE_XRC_RCV_QP] = ib_uverbs_create_xrc_rcv_qp, 114 [IB_USER_VERBS_CMD_MODIFY_XRC_RCV_QP] = ib_uverbs_modify_xrc_rcv_qp, 115 [IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP] = ib_uverbs_query_xrc_rcv_qp, 116 [IB_USER_VERBS_CMD_REG_XRC_RCV_QP] = ib_uverbs_reg_xrc_rcv_qp, 117 [IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP] = ib_uverbs_unreg_xrc_rcv_qp, 118}; 119 120#ifdef __linux__ 121/* BSD Does not require a fake mountpoint for all files. */ 122static struct vfsmount *uverbs_event_mnt; 123#endif 124 125static void ib_uverbs_add_one(struct ib_device *device); 126static void ib_uverbs_remove_one(struct ib_device *device); 127 128static void ib_uverbs_release_dev(struct kref *ref) 129{ 130 struct ib_uverbs_device *dev = 131 container_of(ref, struct ib_uverbs_device, ref); 132 133 complete(&dev->comp); 134} 135 136static void ib_uverbs_release_event_file(struct kref *ref) 137{ 138 struct ib_uverbs_event_file *file = 139 container_of(ref, struct ib_uverbs_event_file, ref); 140 141 kfree(file); 142} 143 144void ib_uverbs_release_ucq(struct ib_uverbs_file *file, 145 struct ib_uverbs_event_file *ev_file, 146 struct ib_ucq_object *uobj) 147{ 148 struct ib_uverbs_event *evt, *tmp; 149 150 if (ev_file) { 151 spin_lock_irq(&ev_file->lock); 152 list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { 153 list_del(&evt->list); 154 kfree(evt); 155 } 156 spin_unlock_irq(&ev_file->lock); 157 158 kref_put(&ev_file->ref, ib_uverbs_release_event_file); 159 } 160 161 spin_lock_irq(&file->async_file->lock); 162 list_for_each_entry_safe(evt, tmp, &uobj->async_list, obj_list) { 163 list_del(&evt->list); 164 kfree(evt); 165 } 166 spin_unlock_irq(&file->async_file->lock); 167} 168 169void ib_uverbs_release_uevent(struct ib_uverbs_file *file, 170 struct ib_uevent_object *uobj) 171{ 172 struct ib_uverbs_event *evt, *tmp; 173 174 spin_lock_irq(&file->async_file->lock); 175 list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { 176 list_del(&evt->list); 177 kfree(evt); 178 } 179 spin_unlock_irq(&file->async_file->lock); 180} 181 182static void ib_uverbs_detach_umcast(struct ib_qp *qp, 183 struct ib_uqp_object *uobj) 184{ 185 struct ib_uverbs_mcast_entry *mcast, *tmp; 186 187 list_for_each_entry_safe(mcast, tmp, &uobj->mcast_list, list) { 188 ib_detach_mcast(qp, &mcast->gid, mcast->lid); 189 list_del(&mcast->list); 190 kfree(mcast); 191 } 192} 193 194static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, 195 struct ib_ucontext *context) 196{ 197 struct ib_uobject *uobj, *tmp; 198 199 if (!context) 200 return 0; 201 202 context->closing = 1; 203 204 list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { 205 struct ib_ah *ah = uobj->object; 206 207 idr_remove_uobj(&ib_uverbs_ah_idr, uobj); 208 ib_destroy_ah(ah); 209 kfree(uobj); 210 } 211 212 list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { 213 struct ib_qp *qp = uobj->object; 214 struct ib_uqp_object *uqp = 215 container_of(uobj, struct ib_uqp_object, uevent.uobject); 216 217 idr_remove_uobj(&ib_uverbs_qp_idr, uobj); 218 ib_uverbs_detach_umcast(qp, uqp); 219 ib_destroy_qp(qp); 220 ib_uverbs_release_uevent(file, &uqp->uevent); 221 kfree(uqp); 222 } 223 224 225 list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { 226 struct ib_srq *srq = uobj->object; 227 struct ib_uevent_object *uevent = 228 container_of(uobj, struct ib_uevent_object, uobject); 229 230 idr_remove_uobj(&ib_uverbs_srq_idr, uobj); 231 ib_destroy_srq(srq); 232 ib_uverbs_release_uevent(file, uevent); 233 kfree(uevent); 234 } 235 236 list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) { 237 struct ib_cq *cq = uobj->object; 238 struct ib_uverbs_event_file *ev_file = cq->cq_context; 239 struct ib_ucq_object *ucq = 240 container_of(uobj, struct ib_ucq_object, uobject); 241 242 idr_remove_uobj(&ib_uverbs_cq_idr, uobj); 243 ib_destroy_cq(cq); 244 ib_uverbs_release_ucq(file, ev_file, ucq); 245 kfree(ucq); 246 } 247 248 /* XXX Free MWs */ 249 250 list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { 251 struct ib_mr *mr = uobj->object; 252 253 idr_remove_uobj(&ib_uverbs_mr_idr, uobj); 254 ib_dereg_mr(mr); 255 kfree(uobj); 256 } 257 258 mutex_lock(&file->device->ib_dev->xrcd_table_mutex); 259 list_for_each_entry_safe(uobj, tmp, &context->xrcd_list, list) { 260 struct ib_xrcd *xrcd = uobj->object; 261 struct ib_uxrc_rcv_object *xrc_qp_obj, *tmp1; 262 struct ib_uxrcd_object *xrcd_uobj = 263 container_of(uobj, struct ib_uxrcd_object, uobject); 264 265 list_for_each_entry_safe(xrc_qp_obj, tmp1, 266 &xrcd_uobj->xrc_reg_qp_list, list) { 267 list_del(&xrc_qp_obj->list); 268 ib_uverbs_cleanup_xrc_rcv_qp(file, xrcd, 269 xrc_qp_obj->qp_num); 270 kfree(xrc_qp_obj); 271 } 272 273 idr_remove_uobj(&ib_uverbs_xrc_domain_idr, uobj); 274 ib_uverbs_dealloc_xrcd(file->device->ib_dev, xrcd); 275 kfree(uobj); 276 } 277 mutex_unlock(&file->device->ib_dev->xrcd_table_mutex); 278 279 list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) { 280 struct ib_pd *pd = uobj->object; 281 282 idr_remove_uobj(&ib_uverbs_pd_idr, uobj); 283 ib_dealloc_pd(pd); 284 kfree(uobj); 285 } 286 287 return context->device->dealloc_ucontext(context); 288} 289 290static void ib_uverbs_release_file(struct kref *ref) 291{ 292 struct ib_uverbs_file *file = 293 container_of(ref, struct ib_uverbs_file, ref); 294 295 module_put(file->device->ib_dev->owner); 296 kref_put(&file->device->ref, ib_uverbs_release_dev); 297 298 kfree(file); 299} 300 301static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf, 302 size_t count, loff_t *pos) 303{ 304 struct ib_uverbs_event_file *file = filp->private_data; 305 struct ib_uverbs_event *event; 306 int eventsz; 307 int ret = 0; 308 309 spin_lock_irq(&file->lock); 310 311 while (list_empty(&file->event_list)) { 312 spin_unlock_irq(&file->lock); 313 314 if (filp->f_flags & O_NONBLOCK) 315 return -EAGAIN; 316 317 if (wait_event_interruptible(file->poll_wait, 318 !list_empty(&file->event_list))) 319 return -ERESTARTSYS; 320 321 spin_lock_irq(&file->lock); 322 } 323 324 event = list_entry(file->event_list.next, struct ib_uverbs_event, list); 325 326 if (file->is_async) 327 eventsz = sizeof (struct ib_uverbs_async_event_desc); 328 else 329 eventsz = sizeof (struct ib_uverbs_comp_event_desc); 330 331 if (eventsz > count) { 332 ret = -EINVAL; 333 event = NULL; 334 } else { 335 list_del(file->event_list.next); 336 if (event->counter) { 337 ++(*event->counter); 338 list_del(&event->obj_list); 339 } 340 } 341 342 spin_unlock_irq(&file->lock); 343 344 if (event) { 345 if (copy_to_user(buf, event, eventsz)) 346 ret = -EFAULT; 347 else 348 ret = eventsz; 349 } 350 351 kfree(event); 352 353 return ret; 354} 355 356static unsigned int ib_uverbs_event_poll(struct file *filp, 357 struct poll_table_struct *wait) 358{ 359 unsigned int pollflags = 0; 360 struct ib_uverbs_event_file *file = filp->private_data; 361 362 file->filp = filp; 363 poll_wait(filp, &file->poll_wait, wait); 364 365 spin_lock_irq(&file->lock); 366 if (!list_empty(&file->event_list)) 367 pollflags = POLLIN | POLLRDNORM; 368 spin_unlock_irq(&file->lock); 369 370 return pollflags; 371} 372 373static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) 374{ 375 struct ib_uverbs_event_file *file = filp->private_data; 376 377 return fasync_helper(fd, filp, on, &file->async_queue); 378} 379 380static int ib_uverbs_event_close(struct inode *inode, struct file *filp) 381{ 382 struct ib_uverbs_event_file *file = filp->private_data; 383 struct ib_uverbs_event *entry, *tmp; 384 385 spin_lock_irq(&file->lock); 386 file->is_closed = 1; 387 list_for_each_entry_safe(entry, tmp, &file->event_list, list) { 388 if (entry->counter) 389 list_del(&entry->obj_list); 390 kfree(entry); 391 } 392 spin_unlock_irq(&file->lock); 393 394 if (file->is_async) { 395 ib_unregister_event_handler(&file->uverbs_file->event_handler); 396 kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); 397 } 398 kref_put(&file->ref, ib_uverbs_release_event_file); 399 400 return 0; 401} 402 403static const struct file_operations uverbs_event_fops = { 404 .owner = THIS_MODULE, 405 .read = ib_uverbs_event_read, 406 .poll = ib_uverbs_event_poll, 407 .release = ib_uverbs_event_close, 408 .fasync = ib_uverbs_event_fasync 409}; 410 411void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) 412{ 413 struct ib_uverbs_event_file *file = cq_context; 414 struct ib_ucq_object *uobj; 415 struct ib_uverbs_event *entry; 416 unsigned long flags; 417 418 if (!file) 419 return; 420 421 spin_lock_irqsave(&file->lock, flags); 422 if (file->is_closed) { 423 spin_unlock_irqrestore(&file->lock, flags); 424 return; 425 } 426 427 entry = kmalloc(sizeof *entry, GFP_ATOMIC); 428 if (!entry) { 429 spin_unlock_irqrestore(&file->lock, flags); 430 return; 431 } 432 433 uobj = container_of(cq->uobject, struct ib_ucq_object, uobject); 434 435 entry->desc.comp.cq_handle = cq->uobject->user_handle; 436 entry->counter = &uobj->comp_events_reported; 437 438 list_add_tail(&entry->list, &file->event_list); 439 list_add_tail(&entry->obj_list, &uobj->comp_list); 440 spin_unlock_irqrestore(&file->lock, flags); 441 442 wake_up_interruptible(&file->poll_wait); 443 if (file->filp) 444 selwakeup(&file->filp->f_selinfo); 445 kill_fasync(&file->async_queue, SIGIO, POLL_IN); 446} 447 448static void ib_uverbs_async_handler(struct ib_uverbs_file *file, 449 __u64 element, __u64 event, 450 struct list_head *obj_list, 451 u32 *counter) 452{ 453 struct ib_uverbs_event *entry; 454 unsigned long flags; 455 456 spin_lock_irqsave(&file->async_file->lock, flags); 457 if (file->async_file->is_closed) { 458 spin_unlock_irqrestore(&file->async_file->lock, flags); 459 return; 460 } 461 462 entry = kmalloc(sizeof *entry, GFP_ATOMIC); 463 if (!entry) { 464 spin_unlock_irqrestore(&file->async_file->lock, flags); 465 return; 466 } 467 468 entry->desc.async.element = element; 469 entry->desc.async.event_type = event; 470 entry->counter = counter; 471 472 list_add_tail(&entry->list, &file->async_file->event_list); 473 if (obj_list) 474 list_add_tail(&entry->obj_list, obj_list); 475 spin_unlock_irqrestore(&file->async_file->lock, flags); 476 477 wake_up_interruptible(&file->async_file->poll_wait); 478 if (file->async_file->filp) 479 selwakeup(&file->async_file->filp->f_selinfo); 480 kill_fasync(&file->async_file->async_queue, SIGIO, POLL_IN); 481} 482 483void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) 484{ 485 struct ib_ucq_object *uobj = container_of(event->element.cq->uobject, 486 struct ib_ucq_object, uobject); 487 488 ib_uverbs_async_handler(uobj->uverbs_file, uobj->uobject.user_handle, 489 event->event, &uobj->async_list, 490 &uobj->async_events_reported); 491} 492 493void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr) 494{ 495 struct ib_uevent_object *uobj; 496 497 uobj = container_of(event->element.qp->uobject, 498 struct ib_uevent_object, uobject); 499 500 ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle, 501 event->event, &uobj->event_list, 502 &uobj->events_reported); 503} 504 505void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr) 506{ 507 struct ib_uevent_object *uobj; 508 509 uobj = container_of(event->element.srq->uobject, 510 struct ib_uevent_object, uobject); 511 512 ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle, 513 event->event, &uobj->event_list, 514 &uobj->events_reported); 515} 516 517void ib_uverbs_event_handler(struct ib_event_handler *handler, 518 struct ib_event *event) 519{ 520 struct ib_uverbs_file *file = 521 container_of(handler, struct ib_uverbs_file, event_handler); 522 523 ib_uverbs_async_handler(file, event->element.port_num, event->event, 524 NULL, NULL); 525} 526 527void ib_uverbs_xrc_rcv_qp_event_handler(struct ib_event *event, 528 void *context_ptr) 529{ 530 ib_uverbs_async_handler(context_ptr, event->element.xrc_qp_num, 531 event->event, NULL, NULL); 532} 533 534struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, 535 int is_async, int *fd) 536{ 537 struct ib_uverbs_event_file *ev_file; 538 struct file *filp; 539 int ret; 540 541 ev_file = kmalloc(sizeof *ev_file, GFP_KERNEL); 542 if (!ev_file) 543 return ERR_PTR(-ENOMEM); 544 545 kref_init(&ev_file->ref); 546 spin_lock_init(&ev_file->lock); 547 INIT_LIST_HEAD(&ev_file->event_list); 548 init_waitqueue_head(&ev_file->poll_wait); 549 ev_file->uverbs_file = uverbs_file; 550 ev_file->async_queue = NULL; 551 ev_file->is_async = is_async; 552 ev_file->is_closed = 0; 553 ev_file->filp = NULL; 554 555 *fd = get_unused_fd(); 556 if (*fd < 0) { 557 ret = *fd; 558 goto err; 559 } 560 561 /* 562 * fops_get() can't fail here, because we're coming from a 563 * system call on a uverbs file, which will already have a 564 * module reference. 565 */ 566#ifdef __linux__ 567 filp = alloc_file(uverbs_event_mnt, dget(uverbs_event_mnt->mnt_root), 568 FMODE_READ, fops_get(&uverbs_event_fops)); 569#else 570 filp = alloc_file(FMODE_READ, fops_get(&uverbs_event_fops)); 571#endif 572 if (!filp) { 573 ret = -ENFILE; 574 goto err_fd; 575 } 576 577 filp->private_data = ev_file; 578 579 return filp; 580 581err_fd: 582 put_unused_fd(*fd); 583 584err: 585 kfree(ev_file); 586 return ERR_PTR(ret); 587} 588 589/* 590 * Look up a completion event file by FD. If lookup is successful, 591 * takes a ref to the event file struct that it returns; if 592 * unsuccessful, returns NULL. 593 */ 594struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd) 595{ 596 struct ib_uverbs_event_file *ev_file = NULL; 597 struct file *filp; 598 599 filp = fget(fd); 600 if (!filp) 601 return NULL; 602 603 if (filp->f_op != &uverbs_event_fops) 604 goto out; 605 606 ev_file = filp->private_data; 607 if (ev_file->is_async) { 608 ev_file = NULL; 609 goto out; 610 } 611 612 kref_get(&ev_file->ref); 613 614out: 615 fput(filp); 616 return ev_file; 617} 618 619static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, 620 size_t count, loff_t *pos) 621{ 622 struct ib_uverbs_file *file = filp->private_data; 623 struct ib_uverbs_cmd_hdr hdr; 624 625 if (count < sizeof hdr) 626 return -EINVAL; 627 628 if (copy_from_user(&hdr, buf, sizeof hdr)) 629 return -EFAULT; 630 631 if (hdr.in_words * 4 != count) 632 return -EINVAL; 633 634 if (hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || 635 !uverbs_cmd_table[hdr.command] || 636 !(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command))) 637 return -EINVAL; 638 639 if (!file->ucontext && 640 hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT) 641 return -EINVAL; 642 643 return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr, 644 hdr.in_words * 4, hdr.out_words * 4); 645} 646 647static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) 648{ 649 struct ib_uverbs_file *file = filp->private_data; 650 651 if (!file->ucontext) 652 return -ENODEV; 653 else 654 return file->device->ib_dev->mmap(file->ucontext, vma); 655} 656 657/* 658 * ib_uverbs_open() does not need the BKL: 659 * 660 * - dev_table[] accesses are protected by map_lock, the 661 * ib_uverbs_device structures are properly reference counted, and 662 * everything else is purely local to the file being created, so 663 * races against other open calls are not a problem; 664 * - there is no ioctl method to race against; 665 * - the device is added to dev_table[] as the last part of module 666 * initialization, the open method will either immediately run 667 * -ENXIO, or all required initialization will be done. 668 */ 669static int ib_uverbs_open(struct inode *inode, struct file *filp) 670{ 671 struct ib_uverbs_device *dev; 672 struct ib_uverbs_file *file; 673 int ret; 674 675 spin_lock(&map_lock); 676 dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; 677 if (dev) 678 kref_get(&dev->ref); 679 spin_unlock(&map_lock); 680 681 if (!dev) 682 return -ENXIO; 683 684 if (!try_module_get(dev->ib_dev->owner)) { 685 ret = -ENODEV; 686 goto err; 687 } 688 689 file = kmalloc(sizeof *file, GFP_KERNEL); 690 if (!file) { 691 ret = -ENOMEM; 692 goto err_module; 693 } 694 695 file->device = dev; 696 file->ucontext = NULL; 697 file->async_file = NULL; 698 kref_init(&file->ref); 699 mutex_init(&file->mutex); 700 701 filp->private_data = file; 702 703 return 0; 704 705err_module: 706 module_put(dev->ib_dev->owner); 707 708err: 709 kref_put(&dev->ref, ib_uverbs_release_dev); 710 return ret; 711} 712 713static int ib_uverbs_close(struct inode *inode, struct file *filp) 714{ 715 struct ib_uverbs_file *file = filp->private_data; 716 717 ib_uverbs_cleanup_ucontext(file, file->ucontext); 718 719 if (file->async_file) 720 kref_put(&file->async_file->ref, ib_uverbs_release_event_file); 721 722 kref_put(&file->ref, ib_uverbs_release_file); 723 724 return 0; 725} 726 727static const struct file_operations uverbs_fops = { 728 .owner = THIS_MODULE, 729 .write = ib_uverbs_write, 730 .open = ib_uverbs_open, 731 .release = ib_uverbs_close 732}; 733 734static const struct file_operations uverbs_mmap_fops = { 735 .owner = THIS_MODULE, 736 .write = ib_uverbs_write, 737 .mmap = ib_uverbs_mmap, 738 .open = ib_uverbs_open, 739 .release = ib_uverbs_close 740}; 741 742static struct ib_client uverbs_client = { 743 .name = "uverbs", 744 .add = ib_uverbs_add_one, 745 .remove = ib_uverbs_remove_one 746}; 747 748static ssize_t show_ibdev(struct device *device, struct device_attribute *attr, 749 char *buf) 750{ 751 struct ib_uverbs_device *dev = dev_get_drvdata(device); 752 753 if (!dev) 754 return -ENODEV; 755 756 return sprintf(buf, "%s\n", dev->ib_dev->name); 757} 758static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 759 760static ssize_t show_dev_abi_version(struct device *device, 761 struct device_attribute *attr, char *buf) 762{ 763 struct ib_uverbs_device *dev = dev_get_drvdata(device); 764 765 if (!dev) 766 return -ENODEV; 767 768 return sprintf(buf, "%d\n", dev->ib_dev->uverbs_abi_ver); 769} 770static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); 771 772static ssize_t show_abi_version(struct class *class, struct class_attribute *attr, char *buf) 773{ 774 return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION); 775} 776static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); 777 778#include <linux/pci.h> 779 780static ssize_t 781show_dev_device(struct device *device, struct device_attribute *attr, char *buf) 782{ 783 struct ib_uverbs_device *dev = dev_get_drvdata(device); 784 785 if (!dev) 786 return -ENODEV; 787 788 return sprintf(buf, "0x%04x\n", 789 ((struct pci_dev *)dev->ib_dev->dma_device)->device); 790} 791static DEVICE_ATTR(device, S_IRUGO, show_dev_device, NULL); 792 793static ssize_t 794show_dev_vendor(struct device *device, struct device_attribute *attr, char *buf) 795{ 796 struct ib_uverbs_device *dev = dev_get_drvdata(device); 797 798 if (!dev) 799 return -ENODEV; 800 801 return sprintf(buf, "0x%04x\n", 802 ((struct pci_dev *)dev->ib_dev->dma_device)->vendor); 803} 804static DEVICE_ATTR(vendor, S_IRUGO, show_dev_vendor, NULL); 805 806struct attribute *device_attrs[] = 807{ 808 &dev_attr_device.attr, 809 &dev_attr_vendor.attr, 810 NULL 811}; 812 813static struct attribute_group device_group = { 814 .name = "device", 815 .attrs = device_attrs 816}; 817 818static void ib_uverbs_add_one(struct ib_device *device) 819{ 820 struct ib_uverbs_device *uverbs_dev; 821 822 if (!device->alloc_ucontext) 823 return; 824 825 uverbs_dev = kzalloc(sizeof *uverbs_dev, GFP_KERNEL); 826 if (!uverbs_dev) 827 return; 828 829 kref_init(&uverbs_dev->ref); 830 init_completion(&uverbs_dev->comp); 831 832 spin_lock(&map_lock); 833 uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); 834 if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) { 835 spin_unlock(&map_lock); 836 goto err; 837 } 838 set_bit(uverbs_dev->devnum, dev_map); 839 spin_unlock(&map_lock); 840 841 uverbs_dev->ib_dev = device; 842 uverbs_dev->num_comp_vectors = device->num_comp_vectors; 843 844 uverbs_dev->cdev = cdev_alloc(); 845 if (!uverbs_dev->cdev) 846 goto err; 847 uverbs_dev->cdev->owner = THIS_MODULE; 848 uverbs_dev->cdev->ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops; 849 kobject_set_name(&uverbs_dev->cdev->kobj, "uverbs%d", uverbs_dev->devnum); 850 if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) 851 goto err_cdev; 852 853 uverbs_dev->dev = device_create(uverbs_class, device->dma_device, 854 uverbs_dev->cdev->dev, uverbs_dev, 855 "uverbs%d", uverbs_dev->devnum); 856 if (IS_ERR(uverbs_dev->dev)) 857 goto err_cdev; 858 859 if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev)) 860 goto err_class; 861 if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version)) 862 goto err_class; 863 if (sysfs_create_group(&uverbs_dev->dev->kobj, &device_group)) 864 goto err_class; 865 866 spin_lock(&map_lock); 867 dev_table[uverbs_dev->devnum] = uverbs_dev; 868 spin_unlock(&map_lock); 869 870 ib_set_client_data(device, &uverbs_client, uverbs_dev); 871 872 return; 873 874err_class: 875 device_destroy(uverbs_class, uverbs_dev->cdev->dev); 876 877err_cdev: 878 cdev_del(uverbs_dev->cdev); 879 clear_bit(uverbs_dev->devnum, dev_map); 880 881err: 882 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); 883 wait_for_completion(&uverbs_dev->comp); 884 kfree(uverbs_dev); 885 return; 886} 887 888static void ib_uverbs_remove_one(struct ib_device *device) 889{ 890 struct ib_uverbs_device *uverbs_dev = ib_get_client_data(device, &uverbs_client); 891 892 if (!uverbs_dev) 893 return; 894 895 sysfs_remove_group(&uverbs_dev->dev->kobj, &device_group); 896 dev_set_drvdata(uverbs_dev->dev, NULL); 897 device_destroy(uverbs_class, uverbs_dev->cdev->dev); 898 cdev_del(uverbs_dev->cdev); 899 900 spin_lock(&map_lock); 901 dev_table[uverbs_dev->devnum] = NULL; 902 spin_unlock(&map_lock); 903 904 clear_bit(uverbs_dev->devnum, dev_map); 905 906 kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); 907 wait_for_completion(&uverbs_dev->comp); 908 kfree(uverbs_dev); 909} 910#ifdef __linux__ 911static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags, 912 const char *dev_name, void *data, 913 struct vfsmount *mnt) 914{ 915 return get_sb_pseudo(fs_type, "infinibandevent:", NULL, 916 INFINIBANDEVENTFS_MAGIC, mnt); 917} 918 919static struct file_system_type uverbs_event_fs = { 920 /* No owner field so module can be unloaded */ 921 .name = "infinibandeventfs", 922 .get_sb = uverbs_event_get_sb, 923 .kill_sb = kill_litter_super 924}; 925#endif 926 927static int __init ib_uverbs_init(void) 928{ 929 int ret; 930 931 spin_lock_init(&map_lock); 932 933 ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES, 934 "infiniband_verbs"); 935 if (ret) { 936 printk(KERN_ERR "user_verbs: couldn't register device number\n"); 937 goto out; 938 } 939 940 uverbs_class = class_create(THIS_MODULE, "infiniband_verbs"); 941 if (IS_ERR(uverbs_class)) { 942 ret = PTR_ERR(uverbs_class); 943 printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n"); 944 goto out_chrdev; 945 } 946 947 ret = class_create_file(uverbs_class, &class_attr_abi_version); 948 if (ret) { 949 printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n"); 950 goto out_class; 951 } 952 953#ifdef __linux__ 954 ret = register_filesystem(&uverbs_event_fs); 955 if (ret) { 956 printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n"); 957 goto out_class; 958 } 959 960 uverbs_event_mnt = kern_mount(&uverbs_event_fs); 961 if (IS_ERR(uverbs_event_mnt)) { 962 ret = PTR_ERR(uverbs_event_mnt); 963 printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n"); 964 goto out_fs; 965 } 966#endif 967 968 ret = ib_register_client(&uverbs_client); 969 if (ret) { 970 printk(KERN_ERR "user_verbs: couldn't register client\n"); 971 goto out_mnt; 972 } 973 974 return 0; 975 976out_mnt: 977#ifdef __linux__ 978 mntput(uverbs_event_mnt); 979 980out_fs: 981 unregister_filesystem(&uverbs_event_fs); 982#endif 983 984out_class: 985 class_destroy(uverbs_class); 986 987out_chrdev: 988 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); 989 990out: 991 return ret; 992} 993 994static void __exit ib_uverbs_cleanup(void) 995{ 996 ib_unregister_client(&uverbs_client); 997#ifdef __linux__ 998 mntput(uverbs_event_mnt); 999 unregister_filesystem(&uverbs_event_fs); 1000#endif 1001 class_destroy(uverbs_class); 1002 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES); 1003 idr_destroy(&ib_uverbs_pd_idr); 1004 idr_destroy(&ib_uverbs_mr_idr); 1005 idr_destroy(&ib_uverbs_mw_idr); 1006 idr_destroy(&ib_uverbs_ah_idr); 1007 idr_destroy(&ib_uverbs_cq_idr); 1008 idr_destroy(&ib_uverbs_qp_idr); 1009 idr_destroy(&ib_uverbs_srq_idr); 1010} 1011 1012module_init(ib_uverbs_init); 1013module_exit(ib_uverbs_cleanup); 1014