The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ofed/drivers/infiniband/core/ib_uverbs_main.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
    3  *
    4  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
    5  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
    6  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
    7  * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
    8  * Copyright (c) 2005 PathScale, Inc. All rights reserved.
    9  *
   10  * This software is available to you under a choice of one of two
   11  * licenses.  You may choose to be licensed under the terms of the GNU
   12  * General Public License (GPL) Version 2, available from the file
   13  * COPYING in the main directory of this source tree, or the
   14  * OpenIB.org BSD license below:
   15  *
   16  *     Redistribution and use in source and binary forms, with or
   17  *     without modification, are permitted provided that the following
   18  *     conditions are met:
   19  *
   20  *      - Redistributions of source code must retain the above
   21  *        copyright notice, this list of conditions and the following
   22  *        disclaimer.
   23  *
   24  *      - Redistributions in binary form must reproduce the above
   25  *        copyright notice, this list of conditions and the following
   26  *        disclaimer in the documentation and/or other materials
   27  *        provided with the distribution.
   28  *
   29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   30  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   32  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   33  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   34  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   35  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   36  * SOFTWARE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __FBSDID("$FreeBSD$");
   41 
   42 #include <linux/module.h>
   43 #include <linux/device.h>
   44 #include <linux/err.h>
   45 #include <linux/fs.h>
   46 #include <linux/poll.h>
   47 #include <linux/sched.h>
   48 #include <linux/file.h>
   49 #include <linux/cdev.h>
   50 #include <linux/slab.h>
   51 #include <linux/pci.h>
   52 #include <linux/lockdep.h>
   53 
   54 #include <asm/uaccess.h>
   55 
   56 #include <rdma/ib.h>
   57 #include <rdma/uverbs_std_types.h>
   58 
   59 #include "uverbs.h"
   60 #include "core_priv.h"
   61 #include "rdma_core.h"
   62 
   63 MODULE_AUTHOR("Roland Dreier");
   64 MODULE_DESCRIPTION("InfiniBand userspace verbs access");
   65 MODULE_LICENSE("Dual BSD/GPL");
   66 
   67 enum {
   68         IB_UVERBS_MAJOR       = 231,
   69         IB_UVERBS_BASE_MINOR  = 192,
   70         IB_UVERBS_MAX_DEVICES = RDMA_MAX_PORTS,
   71         IB_UVERBS_NUM_FIXED_MINOR = 32,
   72         IB_UVERBS_NUM_DYNAMIC_MINOR = IB_UVERBS_MAX_DEVICES - IB_UVERBS_NUM_FIXED_MINOR,
   73 };
   74 
   75 #define IB_UVERBS_BASE_DEV      MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR)
   76 
   77 static dev_t dynamic_uverbs_dev;
   78 static struct class *uverbs_class;
   79 
   80 static DEFINE_IDA(uverbs_ida);
   81 static void ib_uverbs_add_one(struct ib_device *device);
   82 static void ib_uverbs_remove_one(struct ib_device *device, void *client_data);
   83 
   84 /*
   85  * Must be called with the ufile->device->disassociate_srcu held, and the lock
   86  * must be held until use of the ucontext is finished.
   87  */
   88 struct ib_ucontext *ib_uverbs_get_ucontext_file(struct ib_uverbs_file *ufile)
   89 {
   90         /*
   91          * We do not hold the hw_destroy_rwsem lock for this flow, instead
   92          * srcu is used. It does not matter if someone races this with
   93          * get_context, we get NULL or valid ucontext.
   94          */
   95         struct ib_ucontext *ucontext = READ_ONCE(ufile->ucontext);
   96 
   97         if (!srcu_dereference(ufile->device->ib_dev,
   98                               &ufile->device->disassociate_srcu))
   99                 return ERR_PTR(-EIO);
  100 
  101         if (!ucontext)
  102                 return ERR_PTR(-EINVAL);
  103 
  104         return ucontext;
  105 }
  106 EXPORT_SYMBOL(ib_uverbs_get_ucontext_file);
  107 
  108 int uverbs_dealloc_mw(struct ib_mw *mw)
  109 {
  110         struct ib_pd *pd = mw->pd;
  111         int ret;
  112 
  113         ret = mw->device->dealloc_mw(mw);
  114         if (!ret)
  115                 atomic_dec(&pd->usecnt);
  116         return ret;
  117 }
  118 
  119 static void ib_uverbs_release_dev(struct device *device)
  120 {
  121         struct ib_uverbs_device *dev =
  122                         container_of(device, struct ib_uverbs_device, dev);
  123 
  124         uverbs_destroy_api(dev->uapi);
  125         cleanup_srcu_struct(&dev->disassociate_srcu);
  126         mutex_destroy(&dev->lists_mutex);
  127         mutex_destroy(&dev->xrcd_tree_mutex);
  128         kfree(dev);
  129 }
  130 
  131 void ib_uverbs_release_ucq(struct ib_uverbs_completion_event_file *ev_file,
  132                            struct ib_ucq_object *uobj)
  133 {
  134         struct ib_uverbs_event *evt, *tmp;
  135 
  136         if (ev_file) {
  137                 spin_lock_irq(&ev_file->ev_queue.lock);
  138                 list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
  139                         list_del(&evt->list);
  140                         kfree(evt);
  141                 }
  142                 spin_unlock_irq(&ev_file->ev_queue.lock);
  143 
  144                 uverbs_uobject_put(&ev_file->uobj);
  145         }
  146 
  147         ib_uverbs_release_uevent(&uobj->uevent);
  148 }
  149 
  150 void ib_uverbs_release_uevent(struct ib_uevent_object *uobj)
  151 {
  152         struct ib_uverbs_async_event_file *async_file =
  153                 READ_ONCE(uobj->uobject.ufile->async_file);
  154         struct ib_uverbs_event *evt, *tmp;
  155 
  156         if (!async_file)
  157                 return;
  158 
  159         spin_lock_irq(&async_file->ev_queue.lock);
  160         list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
  161                 list_del(&evt->list);
  162                 kfree(evt);
  163         }
  164         spin_unlock_irq(&async_file->ev_queue.lock);
  165 }
  166 
  167 void ib_uverbs_detach_umcast(struct ib_qp *qp,
  168                              struct ib_uqp_object *uobj)
  169 {
  170         struct ib_uverbs_mcast_entry *mcast, *tmp;
  171 
  172         list_for_each_entry_safe(mcast, tmp, &uobj->mcast_list, list) {
  173                 ib_detach_mcast(qp, &mcast->gid, mcast->lid);
  174                 list_del(&mcast->list);
  175                 kfree(mcast);
  176         }
  177 }
  178 
  179 static void ib_uverbs_comp_dev(struct ib_uverbs_device *dev)
  180 {
  181         complete(&dev->comp);
  182 }
  183 
  184 void ib_uverbs_release_file(struct kref *ref)
  185 {
  186         struct ib_uverbs_file *file =
  187                 container_of(ref, struct ib_uverbs_file, ref);
  188         struct ib_device *ib_dev;
  189         int srcu_key;
  190 
  191         release_ufile_idr_uobject(file);
  192 
  193         srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
  194         ib_dev = srcu_dereference(file->device->ib_dev,
  195                                   &file->device->disassociate_srcu);
  196         if (ib_dev && !ib_dev->disassociate_ucontext)
  197                 module_put(ib_dev->owner);
  198         srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
  199 
  200         if (atomic_dec_and_test(&file->device->refcount))
  201                 ib_uverbs_comp_dev(file->device);
  202 
  203         if (file->async_file)
  204                 uverbs_uobject_put(&file->async_file->uobj);
  205         put_device(&file->device->dev);
  206 
  207         mutex_destroy(&file->umap_lock);
  208         mutex_destroy(&file->ucontext_lock);
  209         kfree(file);
  210 }
  211 
  212 static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,
  213                                     struct file *filp, char __user *buf,
  214                                     size_t count, loff_t *pos,
  215                                     size_t eventsz)
  216 {
  217         struct ib_uverbs_event *event;
  218         int ret = 0;
  219 
  220         spin_lock_irq(&ev_queue->lock);
  221 
  222         while (list_empty(&ev_queue->event_list)) {
  223                 spin_unlock_irq(&ev_queue->lock);
  224 
  225                 if (filp->f_flags & O_NONBLOCK)
  226                         return -EAGAIN;
  227 
  228                 if (wait_event_interruptible(ev_queue->poll_wait,
  229                                              (!list_empty(&ev_queue->event_list) ||
  230                                               ev_queue->is_closed)))
  231                         return -ERESTARTSYS;
  232 
  233                 spin_lock_irq(&ev_queue->lock);
  234 
  235                 /* If device was disassociated and no event exists set an error */
  236                 if (list_empty(&ev_queue->event_list) && ev_queue->is_closed) {
  237                         spin_unlock_irq(&ev_queue->lock);
  238                         return -EIO;
  239                 }
  240         }
  241 
  242         event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list);
  243 
  244         if (eventsz > count) {
  245                 ret   = -EINVAL;
  246                 event = NULL;
  247         } else {
  248                 list_del(ev_queue->event_list.next);
  249                 if (event->counter) {
  250                         ++(*event->counter);
  251                         list_del(&event->obj_list);
  252                 }
  253         }
  254 
  255         spin_unlock_irq(&ev_queue->lock);
  256 
  257         if (event) {
  258                 if (copy_to_user(buf, event, eventsz))
  259                         ret = -EFAULT;
  260                 else
  261                         ret = eventsz;
  262         }
  263 
  264         kfree(event);
  265 
  266         return ret;
  267 }
  268 
  269 static ssize_t ib_uverbs_async_event_read(struct file *filp, char __user *buf,
  270                                           size_t count, loff_t *pos)
  271 {
  272         struct ib_uverbs_async_event_file *file = filp->private_data;
  273 
  274         return ib_uverbs_event_read(&file->ev_queue, filp, buf, count, pos,
  275                                     sizeof(struct ib_uverbs_async_event_desc));
  276 }
  277 
  278 static ssize_t ib_uverbs_comp_event_read(struct file *filp, char __user *buf,
  279                                          size_t count, loff_t *pos)
  280 {
  281         struct ib_uverbs_completion_event_file *comp_ev_file =
  282                 filp->private_data;
  283 
  284         return ib_uverbs_event_read(&comp_ev_file->ev_queue, filp, buf, count,
  285                                     pos,
  286                                     sizeof(struct ib_uverbs_comp_event_desc));
  287 }
  288 
  289 static __poll_t ib_uverbs_event_poll(struct ib_uverbs_event_queue *ev_queue,
  290                                          struct file *filp,
  291                                          struct poll_table_struct *wait)
  292 {
  293         __poll_t pollflags = 0;
  294 
  295         poll_wait(filp, &ev_queue->poll_wait, wait);
  296 
  297         spin_lock_irq(&ev_queue->lock);
  298         if (!list_empty(&ev_queue->event_list))
  299                 pollflags = POLLIN | POLLRDNORM;
  300         spin_unlock_irq(&ev_queue->lock);
  301 
  302         return pollflags;
  303 }
  304 
  305 static __poll_t ib_uverbs_async_event_poll(struct file *filp,
  306                                                struct poll_table_struct *wait)
  307 {
  308         struct ib_uverbs_async_event_file *file = filp->private_data;
  309 
  310         return ib_uverbs_event_poll(&file->ev_queue, filp, wait);
  311 }
  312 
  313 static __poll_t ib_uverbs_comp_event_poll(struct file *filp,
  314                                               struct poll_table_struct *wait)
  315 {
  316         struct ib_uverbs_completion_event_file *comp_ev_file =
  317                 filp->private_data;
  318 
  319         return ib_uverbs_event_poll(&comp_ev_file->ev_queue, filp, wait);
  320 }
  321 
  322 static int ib_uverbs_async_event_fasync(int fd, struct file *filp, int on)
  323 {
  324         struct ib_uverbs_async_event_file *file = filp->private_data;
  325 
  326         return fasync_helper(fd, filp, on, &file->ev_queue.async_queue);
  327 }
  328 
  329 static int ib_uverbs_comp_event_fasync(int fd, struct file *filp, int on)
  330 {
  331         struct ib_uverbs_completion_event_file *comp_ev_file =
  332                 filp->private_data;
  333 
  334         return fasync_helper(fd, filp, on, &comp_ev_file->ev_queue.async_queue);
  335 }
  336 
  337 const struct file_operations uverbs_event_fops = {
  338         .owner   = THIS_MODULE,
  339         .read    = ib_uverbs_comp_event_read,
  340         .poll    = ib_uverbs_comp_event_poll,
  341         .release = uverbs_uobject_fd_release,
  342         .fasync  = ib_uverbs_comp_event_fasync,
  343         .llseek  = no_llseek,
  344 };
  345 
  346 const struct file_operations uverbs_async_event_fops = {
  347         .owner   = THIS_MODULE,
  348         .read    = ib_uverbs_async_event_read,
  349         .poll    = ib_uverbs_async_event_poll,
  350         .release = uverbs_uobject_fd_release,
  351         .fasync  = ib_uverbs_async_event_fasync,
  352         .llseek  = no_llseek,
  353 };
  354 
  355 void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
  356 {
  357         struct ib_uverbs_event_queue   *ev_queue = cq_context;
  358         struct ib_ucq_object           *uobj;
  359         struct ib_uverbs_event         *entry;
  360         unsigned long                   flags;
  361 
  362         if (!ev_queue)
  363                 return;
  364 
  365         spin_lock_irqsave(&ev_queue->lock, flags);
  366         if (ev_queue->is_closed) {
  367                 spin_unlock_irqrestore(&ev_queue->lock, flags);
  368                 return;
  369         }
  370 
  371         entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
  372         if (!entry) {
  373                 spin_unlock_irqrestore(&ev_queue->lock, flags);
  374                 return;
  375         }
  376 
  377         uobj = cq->uobject;
  378 
  379         entry->desc.comp.cq_handle = cq->uobject->uevent.uobject.user_handle;
  380         entry->counter             = &uobj->comp_events_reported;
  381 
  382         list_add_tail(&entry->list, &ev_queue->event_list);
  383         list_add_tail(&entry->obj_list, &uobj->comp_list);
  384         spin_unlock_irqrestore(&ev_queue->lock, flags);
  385 
  386         wake_up_interruptible(&ev_queue->poll_wait);
  387         kill_fasync(&ev_queue->async_queue, SIGIO, POLL_IN);
  388 }
  389 
  390 static void
  391 ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file,
  392                         __u64 element, __u64 event, struct list_head *obj_list,
  393                         u32 *counter)
  394 {
  395         struct ib_uverbs_event *entry;
  396         unsigned long flags;
  397 
  398         if (!async_file)
  399                 return;
  400 
  401         spin_lock_irqsave(&async_file->ev_queue.lock, flags);
  402         if (async_file->ev_queue.is_closed) {
  403                 spin_unlock_irqrestore(&async_file->ev_queue.lock, flags);
  404                 return;
  405         }
  406 
  407         entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
  408         if (!entry) {
  409                 spin_unlock_irqrestore(&async_file->ev_queue.lock, flags);
  410                 return;
  411         }
  412 
  413         entry->desc.async.element = element;
  414         entry->desc.async.event_type = event;
  415         entry->desc.async.reserved = 0;
  416         entry->counter = counter;
  417 
  418         list_add_tail(&entry->list, &async_file->ev_queue.event_list);
  419         if (obj_list)
  420                 list_add_tail(&entry->obj_list, obj_list);
  421         spin_unlock_irqrestore(&async_file->ev_queue.lock, flags);
  422 
  423         wake_up_interruptible(&async_file->ev_queue.poll_wait);
  424         kill_fasync(&async_file->ev_queue.async_queue, SIGIO, POLL_IN);
  425 }
  426 
  427 static void uverbs_uobj_event(struct ib_uevent_object *eobj,
  428                               struct ib_event *event)
  429 {
  430         ib_uverbs_async_handler(READ_ONCE(eobj->uobject.ufile->async_file),
  431                                 eobj->uobject.user_handle, event->event,
  432                                 &eobj->event_list, &eobj->events_reported);
  433 }
  434 
  435 void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
  436 {
  437         uverbs_uobj_event(&event->element.cq->uobject->uevent, event);
  438 }
  439 
  440 void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
  441 {
  442         /* for XRC target qp's, check that qp is live */
  443         if (!event->element.qp->uobject)
  444                 return;
  445 
  446         uverbs_uobj_event(&event->element.qp->uobject->uevent, event);
  447 }
  448 
  449 void ib_uverbs_wq_event_handler(struct ib_event *event, void *context_ptr)
  450 {
  451         uverbs_uobj_event(&event->element.wq->uobject->uevent, event);
  452 }
  453 
  454 void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr)
  455 {
  456         uverbs_uobj_event(&event->element.srq->uobject->uevent, event);
  457 }
  458 
  459 static void ib_uverbs_event_handler(struct ib_event_handler *handler,
  460                                     struct ib_event *event)
  461 {
  462         ib_uverbs_async_handler(
  463                 container_of(handler, struct ib_uverbs_async_event_file,
  464                              event_handler),
  465                 event->element.port_num, event->event, NULL, NULL);
  466 }
  467 
  468 void ib_uverbs_init_event_queue(struct ib_uverbs_event_queue *ev_queue)
  469 {
  470         spin_lock_init(&ev_queue->lock);
  471         INIT_LIST_HEAD(&ev_queue->event_list);
  472         init_waitqueue_head(&ev_queue->poll_wait);
  473         ev_queue->is_closed   = 0;
  474         ev_queue->async_queue = NULL;
  475 }
  476 
  477 void ib_uverbs_init_async_event_file(
  478         struct ib_uverbs_async_event_file *async_file)
  479 {
  480         struct ib_uverbs_file *uverbs_file = async_file->uobj.ufile;
  481         struct ib_device *ib_dev = async_file->uobj.context->device;
  482 
  483         ib_uverbs_init_event_queue(&async_file->ev_queue);
  484 
  485         /* The first async_event_file becomes the default one for the file. */
  486         mutex_lock(&uverbs_file->ucontext_lock);
  487         if (!uverbs_file->async_file) {
  488                 /* Pairs with the put in ib_uverbs_release_file */
  489                 uverbs_uobject_get(&async_file->uobj);
  490                 atomic_store_rel_ptr((uintptr_t *)&uverbs_file->async_file, (uintptr_t)async_file);
  491         }
  492         mutex_unlock(&uverbs_file->ucontext_lock);
  493 
  494         INIT_IB_EVENT_HANDLER(&async_file->event_handler, ib_dev,
  495                               ib_uverbs_event_handler);
  496         ib_register_event_handler(&async_file->event_handler);
  497 }
  498 
  499 static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr,
  500                           struct ib_uverbs_ex_cmd_hdr *ex_hdr, size_t count,
  501                           const struct uverbs_api_write_method *method_elm)
  502 {
  503         if (method_elm->is_ex) {
  504                 count -= sizeof(*hdr) + sizeof(*ex_hdr);
  505 
  506                 if ((hdr->in_words + ex_hdr->provider_in_words) * 8 != count)
  507                         return -EINVAL;
  508 
  509                 if (hdr->in_words * 8 < method_elm->req_size)
  510                         return -ENOSPC;
  511 
  512                 if (ex_hdr->cmd_hdr_reserved)
  513                         return -EINVAL;
  514 
  515                 if (ex_hdr->response) {
  516                         if (!hdr->out_words && !ex_hdr->provider_out_words)
  517                                 return -EINVAL;
  518 
  519                         if (hdr->out_words * 8 < method_elm->resp_size)
  520                                 return -ENOSPC;
  521 
  522                         if (!access_ok(u64_to_user_ptr(ex_hdr->response),
  523                                        (hdr->out_words + ex_hdr->provider_out_words) * 8))
  524                                 return -EFAULT;
  525                 } else {
  526                         if (hdr->out_words || ex_hdr->provider_out_words)
  527                                 return -EINVAL;
  528                 }
  529 
  530                 return 0;
  531         }
  532 
  533         /* not extended command */
  534         if (hdr->in_words * 4 != count)
  535                 return -EINVAL;
  536 
  537         if (count < method_elm->req_size + sizeof(hdr)) {
  538                 /*
  539                  * rdma-core v18 and v19 have a bug where they send DESTROY_CQ
  540                  * with a 16 byte write instead of 24. Old kernels didn't
  541                  * check the size so they allowed this. Now that the size is
  542                  * checked provide a compatibility work around to not break
  543                  * those userspaces.
  544                  */
  545                 if (hdr->command == IB_USER_VERBS_CMD_DESTROY_CQ &&
  546                     count == 16) {
  547                         hdr->in_words = 6;
  548                         return 0;
  549                 }
  550                 return -ENOSPC;
  551         }
  552         if (hdr->out_words * 4 < method_elm->resp_size)
  553                 return -ENOSPC;
  554 
  555         return 0;
  556 }
  557 
  558 static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
  559                              size_t count, loff_t *pos)
  560 {
  561         struct ib_uverbs_file *file = filp->private_data;
  562         const struct uverbs_api_write_method *method_elm;
  563         struct uverbs_api *uapi = file->device->uapi;
  564         struct ib_uverbs_ex_cmd_hdr ex_hdr;
  565         struct ib_uverbs_cmd_hdr hdr;
  566         struct uverbs_attr_bundle bundle;
  567         int srcu_key;
  568         ssize_t ret;
  569 
  570         if (!ib_safe_file_access(filp)) {
  571                 pr_warn_once("uverbs_write: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n",
  572                             current->pid, current->comm);
  573                 return -EACCES;
  574         }
  575 
  576         if (count < sizeof(hdr))
  577                 return -EINVAL;
  578 
  579         if (copy_from_user(&hdr, buf, sizeof(hdr)))
  580                 return -EFAULT;
  581 
  582         method_elm = uapi_get_method(uapi, hdr.command);
  583         if (IS_ERR(method_elm))
  584                 return PTR_ERR(method_elm);
  585 
  586         if (method_elm->is_ex) {
  587                 if (count < (sizeof(hdr) + sizeof(ex_hdr)))
  588                         return -EINVAL;
  589                 if (copy_from_user(&ex_hdr, buf + sizeof(hdr), sizeof(ex_hdr)))
  590                         return -EFAULT;
  591         }
  592 
  593         ret = verify_hdr(&hdr, &ex_hdr, count, method_elm);
  594         if (ret)
  595                 return ret;
  596 
  597         srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
  598 
  599         buf += sizeof(hdr);
  600 
  601         memset(bundle.attr_present, 0, sizeof(bundle.attr_present));
  602         bundle.ufile = file;
  603         bundle.context = NULL; /* only valid if bundle has uobject */
  604         if (!method_elm->is_ex) {
  605                 size_t in_len = hdr.in_words * 4 - sizeof(hdr);
  606                 size_t out_len = hdr.out_words * 4;
  607                 u64 response = 0;
  608 
  609                 if (method_elm->has_udata) {
  610                         bundle.driver_udata.inlen =
  611                                 in_len - method_elm->req_size;
  612                         in_len = method_elm->req_size;
  613                         if (bundle.driver_udata.inlen)
  614                                 bundle.driver_udata.inbuf = buf + in_len;
  615                         else
  616                                 bundle.driver_udata.inbuf = NULL;
  617                 } else {
  618                         memset(&bundle.driver_udata, 0,
  619                                sizeof(bundle.driver_udata));
  620                 }
  621 
  622                 if (method_elm->has_resp) {
  623                         /*
  624                          * The macros check that if has_resp is set
  625                          * then the command request structure starts
  626                          * with a '__aligned u64 response' member.
  627                          */
  628                         ret = get_user(response, (const u64 __user *)buf);
  629                         if (ret)
  630                                 goto out_unlock;
  631 
  632                         if (method_elm->has_udata) {
  633                                 bundle.driver_udata.outlen =
  634                                         out_len - method_elm->resp_size;
  635                                 out_len = method_elm->resp_size;
  636                                 if (bundle.driver_udata.outlen)
  637                                         bundle.driver_udata.outbuf =
  638                                                 u64_to_user_ptr(response +
  639                                                                 out_len);
  640                                 else
  641                                         bundle.driver_udata.outbuf = NULL;
  642                         }
  643                 } else {
  644                         bundle.driver_udata.outlen = 0;
  645                         bundle.driver_udata.outbuf = NULL;
  646                 }
  647 
  648                 ib_uverbs_init_udata_buf_or_null(
  649                         &bundle.ucore, buf, u64_to_user_ptr(response),
  650                         in_len, out_len);
  651         } else {
  652                 buf += sizeof(ex_hdr);
  653 
  654                 ib_uverbs_init_udata_buf_or_null(&bundle.ucore, buf,
  655                                         u64_to_user_ptr(ex_hdr.response),
  656                                         hdr.in_words * 8, hdr.out_words * 8);
  657 
  658                 ib_uverbs_init_udata_buf_or_null(
  659                         &bundle.driver_udata, buf + bundle.ucore.inlen,
  660                         u64_to_user_ptr(ex_hdr.response + bundle.ucore.outlen),
  661                         ex_hdr.provider_in_words * 8,
  662                         ex_hdr.provider_out_words * 8);
  663 
  664         }
  665 
  666         ret = method_elm->handler(&bundle);
  667 out_unlock:
  668         srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
  669         return (ret) ? : count;
  670 }
  671 
  672 static const struct vm_operations_struct rdma_umap_ops;
  673 
  674 static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma)
  675 {
  676         struct ib_uverbs_file *file = filp->private_data;
  677         struct ib_ucontext *ucontext;
  678         int ret = 0;
  679         int srcu_key;
  680 
  681         srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
  682         ucontext = ib_uverbs_get_ucontext_file(file);
  683         if (IS_ERR(ucontext)) {
  684                 ret = PTR_ERR(ucontext);
  685                 goto out;
  686         }
  687         vma->vm_ops = &rdma_umap_ops;
  688         ret = ucontext->device->mmap(ucontext, vma);
  689 out:
  690         srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
  691         return ret;
  692 }
  693 
  694 /*
  695  * The VMA has been dup'd, initialize the vm_private_data with a new tracking
  696  * struct
  697  */
  698 static void rdma_umap_open(struct vm_area_struct *vma)
  699 {
  700         struct ib_uverbs_file *ufile = vma->vm_file->private_data;
  701         struct rdma_umap_priv *opriv = vma->vm_private_data;
  702         struct rdma_umap_priv *priv;
  703 
  704         if (!opriv)
  705                 return;
  706 
  707         /* We are racing with disassociation */
  708         if (!down_read_trylock(&ufile->hw_destroy_rwsem))
  709                 goto out_zap;
  710         /*
  711          * Disassociation already completed, the VMA should already be zapped.
  712          */
  713         if (!ufile->ucontext)
  714                 goto out_unlock;
  715 
  716         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  717         if (!priv)
  718                 goto out_unlock;
  719         rdma_umap_priv_init(priv, vma, opriv->entry);
  720 
  721         up_read(&ufile->hw_destroy_rwsem);
  722         return;
  723 
  724 out_unlock:
  725         up_read(&ufile->hw_destroy_rwsem);
  726 out_zap:
  727         /*
  728          * We can't allow the VMA to be created with the actual IO pages, that
  729          * would break our API contract, and it can't be stopped at this
  730          * point, so zap it.
  731          */
  732         vma->vm_private_data = NULL;
  733         zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start);
  734 }
  735 
  736 static void rdma_umap_close(struct vm_area_struct *vma)
  737 {
  738         struct ib_uverbs_file *ufile = vma->vm_file->private_data;
  739         struct rdma_umap_priv *priv = vma->vm_private_data;
  740 
  741         if (!priv)
  742                 return;
  743 
  744         /*
  745          * The vma holds a reference on the struct file that created it, which
  746          * in turn means that the ib_uverbs_file is guaranteed to exist at
  747          * this point.
  748          */
  749         mutex_lock(&ufile->umap_lock);
  750 
  751         list_del(&priv->list);
  752         mutex_unlock(&ufile->umap_lock);
  753         kfree(priv);
  754 }
  755 
  756 static const struct vm_operations_struct rdma_umap_ops = {
  757         .open = rdma_umap_open,
  758         .close = rdma_umap_close,
  759 };
  760 
  761 void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
  762 {
  763         struct rdma_umap_priv *priv, *next_priv;
  764 
  765         lockdep_assert_held(&ufile->hw_destroy_rwsem);
  766 
  767         while (1) {
  768                 struct mm_struct *mm = NULL;
  769 
  770                 /* Get an arbitrary mm pointer that hasn't been cleaned yet */
  771                 mutex_lock(&ufile->umap_lock);
  772                 while (!list_empty(&ufile->umaps)) {
  773                         int ret;
  774 
  775                         priv = list_first_entry(&ufile->umaps,
  776                                                 struct rdma_umap_priv, list);
  777                         mm = priv->vma->vm_mm;
  778                         ret = mmget_not_zero(mm);
  779                         if (!ret) {
  780                                 list_del_init(&priv->list);
  781                                 if (priv->entry) {
  782                                         rdma_user_mmap_entry_put(priv->entry);
  783                                         priv->entry = NULL;
  784                                 }
  785                                 mm = NULL;
  786                                 continue;
  787                         }
  788                         break;
  789                 }
  790                 mutex_unlock(&ufile->umap_lock);
  791                 if (!mm)
  792                         return;
  793 
  794                 /*
  795                  * The umap_lock is nested under mmap_sem since it used within
  796                  * the vma_ops callbacks, so we have to clean the list one mm
  797                  * at a time to get the lock ordering right. Typically there
  798                  * will only be one mm, so no big deal.
  799                  */
  800                 down_read(&mm->mmap_sem);
  801                 mutex_lock(&ufile->umap_lock);
  802                 list_for_each_entry_safe (priv, next_priv, &ufile->umaps,
  803                                           list) {
  804                         struct vm_area_struct *vma = priv->vma;
  805 
  806                         if (vma->vm_mm != mm)
  807                                 continue;
  808                         list_del_init(&priv->list);
  809 
  810                         zap_vma_ptes(vma, vma->vm_start,
  811                                      vma->vm_end - vma->vm_start);
  812                 }
  813                 mutex_unlock(&ufile->umap_lock);
  814                 up_read(&mm->mmap_sem);
  815                 mmput(mm);
  816         }
  817 }
  818 
  819 /*
  820  * ib_uverbs_open() does not need the BKL:
  821  *
  822  *  - the ib_uverbs_device structures are properly reference counted and
  823  *    everything else is purely local to the file being created, so
  824  *    races against other open calls are not a problem;
  825  *  - there is no ioctl method to race against;
  826  *  - the open method will either immediately run -ENXIO, or all
  827  *    required initialization will be done.
  828  */
  829 static int ib_uverbs_open(struct inode *inode, struct file *filp)
  830 {
  831         struct ib_uverbs_device *dev;
  832         struct ib_uverbs_file *file;
  833         struct ib_device *ib_dev;
  834         int ret;
  835         int module_dependent;
  836         int srcu_key;
  837 
  838         dev = container_of(inode->i_cdev->si_drv1, struct ib_uverbs_device, cdev);
  839         if (!atomic_inc_not_zero(&dev->refcount))
  840                 return -ENXIO;
  841 
  842         get_device(&dev->dev);
  843         srcu_key = srcu_read_lock(&dev->disassociate_srcu);
  844         mutex_lock(&dev->lists_mutex);
  845         ib_dev = srcu_dereference(dev->ib_dev,
  846                                   &dev->disassociate_srcu);
  847         if (!ib_dev) {
  848                 ret = -EIO;
  849                 goto err;
  850         }
  851 
  852         /* In case IB device supports disassociate ucontext, there is no hard
  853          * dependency between uverbs device and its low level device.
  854          */
  855         module_dependent = !(ib_dev->disassociate_ucontext);
  856 
  857         if (module_dependent) {
  858                 if (!try_module_get(ib_dev->owner)) {
  859                         ret = -ENODEV;
  860                         goto err;
  861                 }
  862         }
  863 
  864         file = kzalloc(sizeof(*file), GFP_KERNEL);
  865         if (!file) {
  866                 ret = -ENOMEM;
  867                 if (module_dependent)
  868                         goto err_module;
  869 
  870                 goto err;
  871         }
  872 
  873         file->device     = dev;
  874         kref_init(&file->ref);
  875         mutex_init(&file->ucontext_lock);
  876 
  877         spin_lock_init(&file->uobjects_lock);
  878         INIT_LIST_HEAD(&file->uobjects);
  879         init_rwsem(&file->hw_destroy_rwsem);
  880         mutex_init(&file->umap_lock);
  881         INIT_LIST_HEAD(&file->umaps);
  882 
  883         filp->private_data = file;
  884         list_add_tail(&file->list, &dev->uverbs_file_list);
  885         mutex_unlock(&dev->lists_mutex);
  886         srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
  887 
  888         setup_ufile_idr_uobject(file);
  889 
  890         return nonseekable_open(inode, filp);
  891 
  892 err_module:
  893         module_put(ib_dev->owner);
  894 
  895 err:
  896         mutex_unlock(&dev->lists_mutex);
  897         srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
  898         if (atomic_dec_and_test(&dev->refcount))
  899                 ib_uverbs_comp_dev(dev);
  900 
  901         put_device(&dev->dev);
  902         return ret;
  903 }
  904 
  905 static int ib_uverbs_close(struct inode *inode, struct file *filp)
  906 {
  907         struct ib_uverbs_file *file = filp->private_data;
  908 
  909         uverbs_destroy_ufile_hw(file, RDMA_REMOVE_CLOSE);
  910 
  911         mutex_lock(&file->device->lists_mutex);
  912         list_del_init(&file->list);
  913         mutex_unlock(&file->device->lists_mutex);
  914 
  915         kref_put(&file->ref, ib_uverbs_release_file);
  916 
  917         return 0;
  918 }
  919 
  920 static const struct file_operations uverbs_fops = {
  921         .owner   = THIS_MODULE,
  922         .write   = ib_uverbs_write,
  923         .open    = ib_uverbs_open,
  924         .release = ib_uverbs_close,
  925         .llseek  = no_llseek,
  926         .unlocked_ioctl = ib_uverbs_ioctl,
  927         .compat_ioctl = NULL,
  928 };
  929 
  930 static const struct file_operations uverbs_mmap_fops = {
  931         .owner   = THIS_MODULE,
  932         .write   = ib_uverbs_write,
  933         .mmap    = ib_uverbs_mmap,
  934         .open    = ib_uverbs_open,
  935         .release = ib_uverbs_close,
  936         .llseek  = no_llseek,
  937         .unlocked_ioctl = ib_uverbs_ioctl,
  938         .compat_ioctl = NULL,
  939 };
  940 
  941 static struct ib_client uverbs_client = {
  942         .name   = "uverbs",
  943         .add    = ib_uverbs_add_one,
  944         .remove = ib_uverbs_remove_one
  945 };
  946 
  947 static ssize_t ibdev_show(struct device *device, struct device_attribute *attr,
  948                           char *buf)
  949 {
  950         struct ib_uverbs_device *dev =
  951                         container_of(device, struct ib_uverbs_device, dev);
  952         int ret = -ENODEV;
  953         int srcu_key;
  954         struct ib_device *ib_dev;
  955 
  956         srcu_key = srcu_read_lock(&dev->disassociate_srcu);
  957         ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
  958         if (ib_dev)
  959                 ret = sprintf(buf, "%s\n", ib_dev->name);
  960         srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
  961 
  962         return ret;
  963 }
  964 static DEVICE_ATTR(ibdev, S_IRUGO, ibdev_show, NULL);
  965 
  966 static ssize_t abi_version_show(struct device *device,
  967                                 struct device_attribute *attr, char *buf)
  968 {
  969         struct ib_uverbs_device *dev =
  970                         container_of(device, struct ib_uverbs_device, dev);
  971         int ret = -ENODEV;
  972         int srcu_key;
  973         struct ib_device *ib_dev;
  974 
  975         srcu_key = srcu_read_lock(&dev->disassociate_srcu);
  976         ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
  977         if (ib_dev)
  978                 ret = sprintf(buf, "%d\n", ib_dev->uverbs_abi_ver);
  979         srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
  980 
  981         return ret;
  982 }
  983 static DEVICE_ATTR(abi_version, S_IRUGO, abi_version_show, NULL);
  984 
  985 static CLASS_ATTR_STRING(abi_version, S_IRUGO,
  986                          __stringify(IB_USER_VERBS_ABI_VERSION));
  987 
  988 static int ib_uverbs_create_uapi(struct ib_device *device,
  989                                  struct ib_uverbs_device *uverbs_dev)
  990 {
  991         struct uverbs_api *uapi;
  992 
  993         uapi = uverbs_alloc_api(device);
  994         if (IS_ERR(uapi))
  995                 return PTR_ERR(uapi);
  996 
  997         uverbs_dev->uapi = uapi;
  998         return 0;
  999 }
 1000 
 1001 static ssize_t
 1002 show_dev_device(struct device *device, struct device_attribute *attr, char *buf)
 1003 {
 1004         struct ib_uverbs_device *dev =
 1005                         container_of(device, struct ib_uverbs_device, dev);
 1006 
 1007         if (!dev->ib_dev->dma_device)
 1008                 return -ENODEV;
 1009 
 1010         return sprintf(buf, "0x%04x\n",
 1011             ((struct pci_dev *)dev->ib_dev->dma_device)->device);
 1012 }
 1013 static DEVICE_ATTR(device, S_IRUGO, show_dev_device, NULL);
 1014 
 1015 static ssize_t
 1016 show_dev_vendor(struct device *device, struct device_attribute *attr, char *buf)
 1017 {
 1018         struct ib_uverbs_device *dev =
 1019                         container_of(device, struct ib_uverbs_device, dev);
 1020 
 1021         if (!dev->ib_dev->dma_device)
 1022                 return -ENODEV;
 1023 
 1024         return sprintf(buf, "0x%04x\n",
 1025             ((struct pci_dev *)dev->ib_dev->dma_device)->vendor);
 1026 }
 1027 static DEVICE_ATTR(vendor, S_IRUGO, show_dev_vendor, NULL);
 1028 
 1029 static struct attribute *ib_dev_attrs[] = {
 1030         &dev_attr_device.attr,
 1031         &dev_attr_vendor.attr,
 1032         NULL,
 1033 };
 1034 
 1035 static const struct attribute_group dev_attr_group = {
 1036         .name = "device",
 1037         .attrs = ib_dev_attrs,
 1038 };
 1039 
 1040 static void ib_uverbs_add_one(struct ib_device *device)
 1041 {
 1042         int devnum;
 1043         dev_t base;
 1044         struct ib_uverbs_device *uverbs_dev;
 1045         int ret;
 1046 
 1047         if (!device->alloc_ucontext)
 1048                 return;
 1049 
 1050         uverbs_dev = kzalloc(sizeof(*uverbs_dev), GFP_KERNEL);
 1051         if (!uverbs_dev)
 1052                 return;
 1053 
 1054         ret = init_srcu_struct(&uverbs_dev->disassociate_srcu);
 1055         if (ret) {
 1056                 kfree(uverbs_dev);
 1057                 return;
 1058         }
 1059 
 1060         uverbs_dev->dev.class = uverbs_class;
 1061         uverbs_dev->dev.parent = device->dev.parent;
 1062         uverbs_dev->dev.release = ib_uverbs_release_dev;
 1063         device_initialize(&uverbs_dev->dev);
 1064         atomic_set(&uverbs_dev->refcount, 1);
 1065         init_completion(&uverbs_dev->comp);
 1066         uverbs_dev->xrcd_tree = RB_ROOT;
 1067         mutex_init(&uverbs_dev->xrcd_tree_mutex);
 1068         mutex_init(&uverbs_dev->lists_mutex);
 1069         INIT_LIST_HEAD(&uverbs_dev->uverbs_file_list);
 1070         rcu_assign_pointer(uverbs_dev->ib_dev, device);
 1071         uverbs_dev->num_comp_vectors = device->num_comp_vectors;
 1072 
 1073         devnum = ida_alloc_max(&uverbs_ida, IB_UVERBS_MAX_DEVICES - 1,
 1074                                GFP_KERNEL);
 1075         if (devnum < 0)
 1076                 goto err;
 1077         uverbs_dev->devnum = devnum;
 1078         if (devnum >= IB_UVERBS_NUM_FIXED_MINOR)
 1079                 base = dynamic_uverbs_dev + devnum - IB_UVERBS_NUM_FIXED_MINOR;
 1080         else
 1081                 base = IB_UVERBS_BASE_DEV + devnum;
 1082 
 1083         if (ib_uverbs_create_uapi(device, uverbs_dev))
 1084                 goto err_uapi;
 1085 
 1086         uverbs_dev->dev.devt = base;
 1087         dev_set_name(&uverbs_dev->dev, "uverbs%d", uverbs_dev->devnum);
 1088 
 1089         cdev_init(&uverbs_dev->cdev,
 1090                   device->mmap ? &uverbs_mmap_fops : &uverbs_fops);
 1091         uverbs_dev->cdev.owner = THIS_MODULE;
 1092 
 1093         kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum);
 1094         ret = cdev_device_add(&uverbs_dev->cdev, &uverbs_dev->dev);
 1095         if (ret)
 1096                 goto err_uapi;
 1097 
 1098         if (device_create_file(&uverbs_dev->dev, &dev_attr_ibdev))
 1099                 goto err_cdev;
 1100         if (device_create_file(&uverbs_dev->dev, &dev_attr_abi_version))
 1101                 goto err_cdev;
 1102         if (sysfs_create_group(&uverbs_dev->dev.kobj, &dev_attr_group))
 1103                 goto err_cdev;
 1104 
 1105         ib_set_client_data(device, &uverbs_client, uverbs_dev);
 1106         return;
 1107 
 1108 err_cdev:
 1109         cdev_device_del(&uverbs_dev->cdev, &uverbs_dev->dev);
 1110 err_uapi:
 1111         ida_free(&uverbs_ida, devnum);
 1112 err:
 1113         if (atomic_dec_and_test(&uverbs_dev->refcount))
 1114                 ib_uverbs_comp_dev(uverbs_dev);
 1115         wait_for_completion(&uverbs_dev->comp);
 1116         put_device(&uverbs_dev->dev);
 1117         return;
 1118 }
 1119 
 1120 static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev,
 1121                                         struct ib_device *ib_dev)
 1122 {
 1123         struct ib_uverbs_file *file;
 1124 
 1125         /* Pending running commands to terminate */
 1126         uverbs_disassociate_api_pre(uverbs_dev);
 1127 
 1128         mutex_lock(&uverbs_dev->lists_mutex);
 1129         while (!list_empty(&uverbs_dev->uverbs_file_list)) {
 1130                 file = list_first_entry(&uverbs_dev->uverbs_file_list,
 1131                                         struct ib_uverbs_file, list);
 1132                 list_del_init(&file->list);
 1133                 kref_get(&file->ref);
 1134 
 1135                 /* We must release the mutex before going ahead and calling
 1136                  * uverbs_cleanup_ufile, as it might end up indirectly calling
 1137                  * uverbs_close, for example due to freeing the resources (e.g
 1138                  * mmput).
 1139                  */
 1140                 mutex_unlock(&uverbs_dev->lists_mutex);
 1141 
 1142                 ib_uverbs_async_handler(READ_ONCE(file->async_file), 0,
 1143                                         IB_EVENT_DEVICE_FATAL, NULL, NULL);
 1144 
 1145                 uverbs_destroy_ufile_hw(file, RDMA_REMOVE_DRIVER_REMOVE);
 1146                 kref_put(&file->ref, ib_uverbs_release_file);
 1147 
 1148                 mutex_lock(&uverbs_dev->lists_mutex);
 1149         }
 1150         mutex_unlock(&uverbs_dev->lists_mutex);
 1151 
 1152         uverbs_disassociate_api(uverbs_dev->uapi);
 1153 }
 1154 
 1155 static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
 1156 {
 1157         struct ib_uverbs_device *uverbs_dev = client_data;
 1158         int wait_clients = 1;
 1159 
 1160         if (!uverbs_dev)
 1161                 return;
 1162 
 1163         cdev_device_del(&uverbs_dev->cdev, &uverbs_dev->dev);
 1164         ida_free(&uverbs_ida, uverbs_dev->devnum);
 1165 
 1166         if (device->disassociate_ucontext) {
 1167                 /* We disassociate HW resources and immediately return.
 1168                  * Userspace will see a EIO errno for all future access.
 1169                  * Upon returning, ib_device may be freed internally and is not
 1170                  * valid any more.
 1171                  * uverbs_device is still available until all clients close
 1172                  * their files, then the uverbs device ref count will be zero
 1173                  * and its resources will be freed.
 1174                  * Note: At this point no more files can be opened since the
 1175                  * cdev was deleted, however active clients can still issue
 1176                  * commands and close their open files.
 1177                  */
 1178                 ib_uverbs_free_hw_resources(uverbs_dev, device);
 1179                 wait_clients = 0;
 1180         }
 1181 
 1182         if (atomic_dec_and_test(&uverbs_dev->refcount))
 1183                 ib_uverbs_comp_dev(uverbs_dev);
 1184         if (wait_clients)
 1185                 wait_for_completion(&uverbs_dev->comp);
 1186 
 1187         put_device(&uverbs_dev->dev);
 1188 }
 1189 
 1190 static char *uverbs_devnode(struct device *dev, umode_t *mode)
 1191 {
 1192         if (mode)
 1193                 *mode = 0666;
 1194         return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
 1195 }
 1196 
 1197 static int __init ib_uverbs_init(void)
 1198 {
 1199         int ret;
 1200 
 1201         ret = register_chrdev_region(IB_UVERBS_BASE_DEV,
 1202                                      IB_UVERBS_NUM_FIXED_MINOR,
 1203                                      "infiniband_verbs");
 1204         if (ret) {
 1205                 pr_err("user_verbs: couldn't register device number\n");
 1206                 goto out;
 1207         }
 1208 
 1209         ret = alloc_chrdev_region(&dynamic_uverbs_dev, 0,
 1210                                   IB_UVERBS_NUM_DYNAMIC_MINOR,
 1211                                   "infiniband_verbs");
 1212         if (ret) {
 1213                 pr_err("couldn't register dynamic device number\n");
 1214                 goto out_alloc;
 1215         }
 1216 
 1217         uverbs_class = class_create(THIS_MODULE, "infiniband_verbs");
 1218         if (IS_ERR(uverbs_class)) {
 1219                 ret = PTR_ERR(uverbs_class);
 1220                 pr_err("user_verbs: couldn't create class infiniband_verbs\n");
 1221                 goto out_chrdev;
 1222         }
 1223 
 1224         uverbs_class->devnode = uverbs_devnode;
 1225 
 1226         ret = class_create_file(uverbs_class, &class_attr_abi_version.attr);
 1227         if (ret) {
 1228                 pr_err("user_verbs: couldn't create abi_version attribute\n");
 1229                 goto out_class;
 1230         }
 1231 
 1232         ret = ib_register_client(&uverbs_client);
 1233         if (ret) {
 1234                 pr_err("user_verbs: couldn't register client\n");
 1235                 goto out_class;
 1236         }
 1237 
 1238         return 0;
 1239 
 1240 out_class:
 1241         class_destroy(uverbs_class);
 1242 
 1243 out_chrdev:
 1244         unregister_chrdev_region(dynamic_uverbs_dev,
 1245                                  IB_UVERBS_NUM_DYNAMIC_MINOR);
 1246 
 1247 out_alloc:
 1248         unregister_chrdev_region(IB_UVERBS_BASE_DEV,
 1249                                  IB_UVERBS_NUM_FIXED_MINOR);
 1250 
 1251 out:
 1252         return ret;
 1253 }
 1254 
 1255 static void __exit ib_uverbs_cleanup(void)
 1256 {
 1257         ib_unregister_client(&uverbs_client);
 1258         class_destroy(uverbs_class);
 1259         unregister_chrdev_region(IB_UVERBS_BASE_DEV,
 1260                                  IB_UVERBS_NUM_FIXED_MINOR);
 1261         unregister_chrdev_region(dynamic_uverbs_dev,
 1262                                  IB_UVERBS_NUM_DYNAMIC_MINOR);
 1263 }
 1264 
 1265 module_init_order(ib_uverbs_init, SI_ORDER_FIFTH);
 1266 module_exit_order(ib_uverbs_cleanup, SI_ORDER_FIFTH);

Cache object: 13de8d5ff66d61cfbb40ee799885a6fb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.