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