linux/drivers/infiniband/core/uverbs_ioctl.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
   3 *
   4 * This software is available to you under a choice of one of two
   5 * licenses.  You may choose to be licensed under the terms of the GNU
   6 * General Public License (GPL) Version 2, available from the file
   7 * COPYING in the main directory of this source tree, or the
   8 * OpenIB.org BSD license below:
   9 *
  10 *     Redistribution and use in source and binary forms, with or
  11 *     without modification, are permitted provided that the following
  12 *     conditions are met:
  13 *
  14 *      - Redistributions of source code must retain the above
  15 *        copyright notice, this list of conditions and the following
  16 *        disclaimer.
  17 *
  18 *      - Redistributions in binary form must reproduce the above
  19 *        copyright notice, this list of conditions and the following
  20 *        disclaimer in the documentation and/or other materials
  21 *        provided with the distribution.
  22 *
  23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30 * SOFTWARE.
  31 */
  32
  33#include <rdma/rdma_user_ioctl.h>
  34#include <rdma/uverbs_ioctl.h>
  35#include "rdma_core.h"
  36#include "uverbs.h"
  37
  38struct bundle_alloc_head {
  39        struct bundle_alloc_head *next;
  40        u8 data[];
  41};
  42
  43struct bundle_priv {
  44        /* Must be first */
  45        struct bundle_alloc_head alloc_head;
  46        struct bundle_alloc_head *allocated_mem;
  47        size_t internal_avail;
  48        size_t internal_used;
  49
  50        struct radix_tree_root *radix;
  51        const struct uverbs_api_ioctl_method *method_elm;
  52        void __rcu **radix_slots;
  53        unsigned long radix_slots_len;
  54        u32 method_key;
  55
  56        struct ib_uverbs_attr __user *user_attrs;
  57        struct ib_uverbs_attr *uattrs;
  58
  59        DECLARE_BITMAP(uobj_finalize, UVERBS_API_ATTR_BKEY_LEN);
  60        DECLARE_BITMAP(spec_finalize, UVERBS_API_ATTR_BKEY_LEN);
  61
  62        /*
  63         * Must be last. bundle ends in a flex array which overlaps
  64         * internal_buffer.
  65         */
  66        struct uverbs_attr_bundle bundle;
  67        u64 internal_buffer[32];
  68};
  69
  70/*
  71 * Each method has an absolute minimum amount of memory it needs to allocate,
  72 * precompute that amount and determine if the onstack memory can be used or
  73 * if allocation is need.
  74 */
  75void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm,
  76                              unsigned int num_attrs)
  77{
  78        struct bundle_priv *pbundle;
  79        size_t bundle_size =
  80                offsetof(struct bundle_priv, internal_buffer) +
  81                sizeof(*pbundle->bundle.attrs) * method_elm->key_bitmap_len +
  82                sizeof(*pbundle->uattrs) * num_attrs;
  83
  84        method_elm->use_stack = bundle_size <= sizeof(*pbundle);
  85        method_elm->bundle_size =
  86                ALIGN(bundle_size + 256, sizeof(*pbundle->internal_buffer));
  87
  88        /* Do not want order-2 allocations for this. */
  89        WARN_ON_ONCE(method_elm->bundle_size > PAGE_SIZE);
  90}
  91
  92/**
  93 * uverbs_alloc() - Quickly allocate memory for use with a bundle
  94 * @bundle: The bundle
  95 * @size: Number of bytes to allocate
  96 * @flags: Allocator flags
  97 *
  98 * The bundle allocator is intended for allocations that are connected with
  99 * processing the system call related to the bundle. The allocated memory is
 100 * always freed once the system call completes, and cannot be freed any other
 101 * way.
 102 *
 103 * This tries to use a small pool of pre-allocated memory for performance.
 104 */
 105__malloc void *_uverbs_alloc(struct uverbs_attr_bundle *bundle, size_t size,
 106                             gfp_t flags)
 107{
 108        struct bundle_priv *pbundle =
 109                container_of(bundle, struct bundle_priv, bundle);
 110        size_t new_used;
 111        void *res;
 112
 113        if (check_add_overflow(size, pbundle->internal_used, &new_used))
 114                return ERR_PTR(-EOVERFLOW);
 115
 116        if (new_used > pbundle->internal_avail) {
 117                struct bundle_alloc_head *buf;
 118
 119                buf = kvmalloc(struct_size(buf, data, size), flags);
 120                if (!buf)
 121                        return ERR_PTR(-ENOMEM);
 122                buf->next = pbundle->allocated_mem;
 123                pbundle->allocated_mem = buf;
 124                return buf->data;
 125        }
 126
 127        res = (void *)pbundle->internal_buffer + pbundle->internal_used;
 128        pbundle->internal_used =
 129                ALIGN(new_used, sizeof(*pbundle->internal_buffer));
 130        if (flags & __GFP_ZERO)
 131                memset(res, 0, size);
 132        return res;
 133}
 134EXPORT_SYMBOL(_uverbs_alloc);
 135
 136static bool uverbs_is_attr_cleared(const struct ib_uverbs_attr *uattr,
 137                                   u16 len)
 138{
 139        if (uattr->len > sizeof(((struct ib_uverbs_attr *)0)->data))
 140                return ib_is_buffer_cleared(u64_to_user_ptr(uattr->data) + len,
 141                                            uattr->len - len);
 142
 143        return !memchr_inv((const void *)&uattr->data + len,
 144                           0, uattr->len - len);
 145}
 146
 147static int uverbs_set_output(const struct uverbs_attr_bundle *bundle,
 148                             const struct uverbs_attr *attr)
 149{
 150        struct bundle_priv *pbundle =
 151                container_of(bundle, struct bundle_priv, bundle);
 152        u16 flags;
 153
 154        flags = pbundle->uattrs[attr->ptr_attr.uattr_idx].flags |
 155                UVERBS_ATTR_F_VALID_OUTPUT;
 156        if (put_user(flags,
 157                     &pbundle->user_attrs[attr->ptr_attr.uattr_idx].flags))
 158                return -EFAULT;
 159        return 0;
 160}
 161
 162static int uverbs_process_idrs_array(struct bundle_priv *pbundle,
 163                                     const struct uverbs_api_attr *attr_uapi,
 164                                     struct uverbs_objs_arr_attr *attr,
 165                                     struct ib_uverbs_attr *uattr,
 166                                     u32 attr_bkey)
 167{
 168        const struct uverbs_attr_spec *spec = &attr_uapi->spec;
 169        size_t array_len;
 170        u32 *idr_vals;
 171        int ret = 0;
 172        size_t i;
 173
 174        if (uattr->attr_data.reserved)
 175                return -EINVAL;
 176
 177        if (uattr->len % sizeof(u32))
 178                return -EINVAL;
 179
 180        array_len = uattr->len / sizeof(u32);
 181        if (array_len < spec->u2.objs_arr.min_len ||
 182            array_len > spec->u2.objs_arr.max_len)
 183                return -EINVAL;
 184
 185        attr->uobjects =
 186                uverbs_alloc(&pbundle->bundle,
 187                             array_size(array_len, sizeof(*attr->uobjects)));
 188        if (IS_ERR(attr->uobjects))
 189                return PTR_ERR(attr->uobjects);
 190
 191        /*
 192         * Since idr is 4B and *uobjects is >= 4B, we can use attr->uobjects
 193         * to store idrs array and avoid additional memory allocation. The
 194         * idrs array is offset to the end of the uobjects array so we will be
 195         * able to read idr and replace with a pointer.
 196         */
 197        idr_vals = (u32 *)(attr->uobjects + array_len) - array_len;
 198
 199        if (uattr->len > sizeof(uattr->data)) {
 200                ret = copy_from_user(idr_vals, u64_to_user_ptr(uattr->data),
 201                                     uattr->len);
 202                if (ret)
 203                        return -EFAULT;
 204        } else {
 205                memcpy(idr_vals, &uattr->data, uattr->len);
 206        }
 207
 208        for (i = 0; i != array_len; i++) {
 209                attr->uobjects[i] = uverbs_get_uobject_from_file(
 210                        spec->u2.objs_arr.obj_type, spec->u2.objs_arr.access,
 211                        idr_vals[i], &pbundle->bundle);
 212                if (IS_ERR(attr->uobjects[i])) {
 213                        ret = PTR_ERR(attr->uobjects[i]);
 214                        break;
 215                }
 216        }
 217
 218        attr->len = i;
 219        __set_bit(attr_bkey, pbundle->spec_finalize);
 220        return ret;
 221}
 222
 223static int uverbs_free_idrs_array(const struct uverbs_api_attr *attr_uapi,
 224                                  struct uverbs_objs_arr_attr *attr,
 225                                  bool commit, struct uverbs_attr_bundle *attrs)
 226{
 227        const struct uverbs_attr_spec *spec = &attr_uapi->spec;
 228        int current_ret;
 229        int ret = 0;
 230        size_t i;
 231
 232        for (i = 0; i != attr->len; i++) {
 233                current_ret = uverbs_finalize_object(attr->uobjects[i],
 234                                                     spec->u2.objs_arr.access,
 235                                                     commit, attrs);
 236                if (!ret)
 237                        ret = current_ret;
 238        }
 239
 240        return ret;
 241}
 242
 243static int uverbs_process_attr(struct bundle_priv *pbundle,
 244                               const struct uverbs_api_attr *attr_uapi,
 245                               struct ib_uverbs_attr *uattr, u32 attr_bkey)
 246{
 247        const struct uverbs_attr_spec *spec = &attr_uapi->spec;
 248        struct uverbs_attr *e = &pbundle->bundle.attrs[attr_bkey];
 249        const struct uverbs_attr_spec *val_spec = spec;
 250        struct uverbs_obj_attr *o_attr;
 251
 252        switch (spec->type) {
 253        case UVERBS_ATTR_TYPE_ENUM_IN:
 254                if (uattr->attr_data.enum_data.elem_id >= spec->u.enum_def.num_elems)
 255                        return -EOPNOTSUPP;
 256
 257                if (uattr->attr_data.enum_data.reserved)
 258                        return -EINVAL;
 259
 260                val_spec = &spec->u2.enum_def.ids[uattr->attr_data.enum_data.elem_id];
 261
 262                /* Currently we only support PTR_IN based enums */
 263                if (val_spec->type != UVERBS_ATTR_TYPE_PTR_IN)
 264                        return -EOPNOTSUPP;
 265
 266                e->ptr_attr.enum_id = uattr->attr_data.enum_data.elem_id;
 267        /* fall through */
 268        case UVERBS_ATTR_TYPE_PTR_IN:
 269                /* Ensure that any data provided by userspace beyond the known
 270                 * struct is zero. Userspace that knows how to use some future
 271                 * longer struct will fail here if used with an old kernel and
 272                 * non-zero content, making ABI compat/discovery simpler.
 273                 */
 274                if (uattr->len > val_spec->u.ptr.len &&
 275                    val_spec->zero_trailing &&
 276                    !uverbs_is_attr_cleared(uattr, val_spec->u.ptr.len))
 277                        return -EOPNOTSUPP;
 278
 279        /* fall through */
 280        case UVERBS_ATTR_TYPE_PTR_OUT:
 281                if (uattr->len < val_spec->u.ptr.min_len ||
 282                    (!val_spec->zero_trailing &&
 283                     uattr->len > val_spec->u.ptr.len))
 284                        return -EINVAL;
 285
 286                if (spec->type != UVERBS_ATTR_TYPE_ENUM_IN &&
 287                    uattr->attr_data.reserved)
 288                        return -EINVAL;
 289
 290                e->ptr_attr.uattr_idx = uattr - pbundle->uattrs;
 291                e->ptr_attr.len = uattr->len;
 292
 293                if (val_spec->alloc_and_copy && !uverbs_attr_ptr_is_inline(e)) {
 294                        void *p;
 295
 296                        p = uverbs_alloc(&pbundle->bundle, uattr->len);
 297                        if (IS_ERR(p))
 298                                return PTR_ERR(p);
 299
 300                        e->ptr_attr.ptr = p;
 301
 302                        if (copy_from_user(p, u64_to_user_ptr(uattr->data),
 303                                           uattr->len))
 304                                return -EFAULT;
 305                } else {
 306                        e->ptr_attr.data = uattr->data;
 307                }
 308                break;
 309
 310        case UVERBS_ATTR_TYPE_IDR:
 311        case UVERBS_ATTR_TYPE_FD:
 312                if (uattr->attr_data.reserved)
 313                        return -EINVAL;
 314
 315                if (uattr->len != 0)
 316                        return -EINVAL;
 317
 318                o_attr = &e->obj_attr;
 319                o_attr->attr_elm = attr_uapi;
 320
 321                /*
 322                 * The type of uattr->data is u64 for UVERBS_ATTR_TYPE_IDR and
 323                 * s64 for UVERBS_ATTR_TYPE_FD. We can cast the u64 to s64
 324                 * here without caring about truncation as we know that the
 325                 * IDR implementation today rejects negative IDs
 326                 */
 327                o_attr->uobject = uverbs_get_uobject_from_file(
 328                        spec->u.obj.obj_type, spec->u.obj.access,
 329                        uattr->data_s64, &pbundle->bundle);
 330                if (IS_ERR(o_attr->uobject))
 331                        return PTR_ERR(o_attr->uobject);
 332                __set_bit(attr_bkey, pbundle->uobj_finalize);
 333
 334                if (spec->u.obj.access == UVERBS_ACCESS_NEW) {
 335                        unsigned int uattr_idx = uattr - pbundle->uattrs;
 336                        s64 id = o_attr->uobject->id;
 337
 338                        /* Copy the allocated id to the user-space */
 339                        if (put_user(id, &pbundle->user_attrs[uattr_idx].data))
 340                                return -EFAULT;
 341                }
 342
 343                break;
 344
 345        case UVERBS_ATTR_TYPE_IDRS_ARRAY:
 346                return uverbs_process_idrs_array(pbundle, attr_uapi,
 347                                                 &e->objs_arr_attr, uattr,
 348                                                 attr_bkey);
 349        default:
 350                return -EOPNOTSUPP;
 351        }
 352
 353        return 0;
 354}
 355
 356/*
 357 * We search the radix tree with the method prefix and now we want to fast
 358 * search the suffix bits to get a particular attribute pointer. It is not
 359 * totally clear to me if this breaks the radix tree encasulation or not, but
 360 * it uses the iter data to determine if the method iter points at the same
 361 * chunk that will store the attribute, if so it just derefs it directly. By
 362 * construction in most kernel configs the method and attrs will all fit in a
 363 * single radix chunk, so in most cases this will have no search. Other cases
 364 * this falls back to a full search.
 365 */
 366static void __rcu **uapi_get_attr_for_method(struct bundle_priv *pbundle,
 367                                             u32 attr_key)
 368{
 369        void __rcu **slot;
 370
 371        if (likely(attr_key < pbundle->radix_slots_len)) {
 372                void *entry;
 373
 374                slot = pbundle->radix_slots + attr_key;
 375                entry = rcu_dereference_raw(*slot);
 376                if (likely(!radix_tree_is_internal_node(entry) && entry))
 377                        return slot;
 378        }
 379
 380        return radix_tree_lookup_slot(pbundle->radix,
 381                                      pbundle->method_key | attr_key);
 382}
 383
 384static int uverbs_set_attr(struct bundle_priv *pbundle,
 385                           struct ib_uverbs_attr *uattr)
 386{
 387        u32 attr_key = uapi_key_attr(uattr->attr_id);
 388        u32 attr_bkey = uapi_bkey_attr(attr_key);
 389        const struct uverbs_api_attr *attr;
 390        void __rcu **slot;
 391        int ret;
 392
 393        slot = uapi_get_attr_for_method(pbundle, attr_key);
 394        if (!slot) {
 395                /*
 396                 * Kernel does not support the attribute but user-space says it
 397                 * is mandatory
 398                 */
 399                if (uattr->flags & UVERBS_ATTR_F_MANDATORY)
 400                        return -EPROTONOSUPPORT;
 401                return 0;
 402        }
 403        attr = rcu_dereference_protected(*slot, true);
 404
 405        /* Reject duplicate attributes from user-space */
 406        if (test_bit(attr_bkey, pbundle->bundle.attr_present))
 407                return -EINVAL;
 408
 409        ret = uverbs_process_attr(pbundle, attr, uattr, attr_bkey);
 410        if (ret)
 411                return ret;
 412
 413        __set_bit(attr_bkey, pbundle->bundle.attr_present);
 414
 415        return 0;
 416}
 417
 418static int ib_uverbs_run_method(struct bundle_priv *pbundle,
 419                                unsigned int num_attrs)
 420{
 421        int (*handler)(struct uverbs_attr_bundle *attrs);
 422        size_t uattrs_size = array_size(sizeof(*pbundle->uattrs), num_attrs);
 423        unsigned int destroy_bkey = pbundle->method_elm->destroy_bkey;
 424        unsigned int i;
 425        int ret;
 426
 427        /* See uverbs_disassociate_api() */
 428        handler = srcu_dereference(
 429                pbundle->method_elm->handler,
 430                &pbundle->bundle.ufile->device->disassociate_srcu);
 431        if (!handler)
 432                return -EIO;
 433
 434        pbundle->uattrs = uverbs_alloc(&pbundle->bundle, uattrs_size);
 435        if (IS_ERR(pbundle->uattrs))
 436                return PTR_ERR(pbundle->uattrs);
 437        if (copy_from_user(pbundle->uattrs, pbundle->user_attrs, uattrs_size))
 438                return -EFAULT;
 439
 440        for (i = 0; i != num_attrs; i++) {
 441                ret = uverbs_set_attr(pbundle, &pbundle->uattrs[i]);
 442                if (unlikely(ret))
 443                        return ret;
 444        }
 445
 446        /* User space did not provide all the mandatory attributes */
 447        if (unlikely(!bitmap_subset(pbundle->method_elm->attr_mandatory,
 448                                    pbundle->bundle.attr_present,
 449                                    pbundle->method_elm->key_bitmap_len)))
 450                return -EINVAL;
 451
 452        if (pbundle->method_elm->has_udata)
 453                uverbs_fill_udata(&pbundle->bundle,
 454                                  &pbundle->bundle.driver_udata,
 455                                  UVERBS_ATTR_UHW_IN, UVERBS_ATTR_UHW_OUT);
 456        else
 457                pbundle->bundle.driver_udata = (struct ib_udata){};
 458
 459        if (destroy_bkey != UVERBS_API_ATTR_BKEY_LEN) {
 460                struct uverbs_obj_attr *destroy_attr =
 461                        &pbundle->bundle.attrs[destroy_bkey].obj_attr;
 462
 463                ret = uobj_destroy(destroy_attr->uobject, &pbundle->bundle);
 464                if (ret)
 465                        return ret;
 466                __clear_bit(destroy_bkey, pbundle->uobj_finalize);
 467
 468                ret = handler(&pbundle->bundle);
 469                uobj_put_destroy(destroy_attr->uobject);
 470        } else {
 471                ret = handler(&pbundle->bundle);
 472        }
 473
 474        /*
 475         * Until the drivers are revised to use the bundle directly we have to
 476         * assume that the driver wrote to its UHW_OUT and flag userspace
 477         * appropriately.
 478         */
 479        if (!ret && pbundle->method_elm->has_udata) {
 480                const struct uverbs_attr *attr =
 481                        uverbs_attr_get(&pbundle->bundle, UVERBS_ATTR_UHW_OUT);
 482
 483                if (!IS_ERR(attr))
 484                        ret = uverbs_set_output(&pbundle->bundle, attr);
 485        }
 486
 487        /*
 488         * EPROTONOSUPPORT is ONLY to be returned if the ioctl framework can
 489         * not invoke the method because the request is not supported.  No
 490         * other cases should return this code.
 491         */
 492        if (WARN_ON_ONCE(ret == -EPROTONOSUPPORT))
 493                return -EINVAL;
 494
 495        return ret;
 496}
 497
 498static int bundle_destroy(struct bundle_priv *pbundle, bool commit)
 499{
 500        unsigned int key_bitmap_len = pbundle->method_elm->key_bitmap_len;
 501        struct bundle_alloc_head *memblock;
 502        unsigned int i;
 503        int ret = 0;
 504
 505        /* fast path for simple uobjects */
 506        i = -1;
 507        while ((i = find_next_bit(pbundle->uobj_finalize, key_bitmap_len,
 508                                  i + 1)) < key_bitmap_len) {
 509                struct uverbs_attr *attr = &pbundle->bundle.attrs[i];
 510                int current_ret;
 511
 512                current_ret = uverbs_finalize_object(
 513                        attr->obj_attr.uobject,
 514                        attr->obj_attr.attr_elm->spec.u.obj.access, commit,
 515                        &pbundle->bundle);
 516                if (!ret)
 517                        ret = current_ret;
 518        }
 519
 520        i = -1;
 521        while ((i = find_next_bit(pbundle->spec_finalize, key_bitmap_len,
 522                                  i + 1)) < key_bitmap_len) {
 523                struct uverbs_attr *attr = &pbundle->bundle.attrs[i];
 524                const struct uverbs_api_attr *attr_uapi;
 525                void __rcu **slot;
 526                int current_ret;
 527
 528                slot = uapi_get_attr_for_method(
 529                        pbundle,
 530                        pbundle->method_key | uapi_bkey_to_key_attr(i));
 531                if (WARN_ON(!slot))
 532                        continue;
 533
 534                attr_uapi = rcu_dereference_protected(*slot, true);
 535
 536                if (attr_uapi->spec.type == UVERBS_ATTR_TYPE_IDRS_ARRAY) {
 537                        current_ret = uverbs_free_idrs_array(
 538                                attr_uapi, &attr->objs_arr_attr, commit,
 539                                &pbundle->bundle);
 540                        if (!ret)
 541                                ret = current_ret;
 542                }
 543        }
 544
 545        for (memblock = pbundle->allocated_mem; memblock;) {
 546                struct bundle_alloc_head *tmp = memblock;
 547
 548                memblock = memblock->next;
 549                kvfree(tmp);
 550        }
 551
 552        return ret;
 553}
 554
 555static int ib_uverbs_cmd_verbs(struct ib_uverbs_file *ufile,
 556                               struct ib_uverbs_ioctl_hdr *hdr,
 557                               struct ib_uverbs_attr __user *user_attrs)
 558{
 559        const struct uverbs_api_ioctl_method *method_elm;
 560        struct uverbs_api *uapi = ufile->device->uapi;
 561        struct radix_tree_iter attrs_iter;
 562        struct bundle_priv *pbundle;
 563        struct bundle_priv onstack;
 564        void __rcu **slot;
 565        int destroy_ret;
 566        int ret;
 567
 568        if (unlikely(hdr->driver_id != uapi->driver_id))
 569                return -EINVAL;
 570
 571        slot = radix_tree_iter_lookup(
 572                &uapi->radix, &attrs_iter,
 573                uapi_key_obj(hdr->object_id) |
 574                        uapi_key_ioctl_method(hdr->method_id));
 575        if (unlikely(!slot))
 576                return -EPROTONOSUPPORT;
 577        method_elm = rcu_dereference_protected(*slot, true);
 578
 579        if (!method_elm->use_stack) {
 580                pbundle = kmalloc(method_elm->bundle_size, GFP_KERNEL);
 581                if (!pbundle)
 582                        return -ENOMEM;
 583                pbundle->internal_avail =
 584                        method_elm->bundle_size -
 585                        offsetof(struct bundle_priv, internal_buffer);
 586                pbundle->alloc_head.next = NULL;
 587                pbundle->allocated_mem = &pbundle->alloc_head;
 588        } else {
 589                pbundle = &onstack;
 590                pbundle->internal_avail = sizeof(pbundle->internal_buffer);
 591                pbundle->allocated_mem = NULL;
 592        }
 593
 594        /* Space for the pbundle->bundle.attrs flex array */
 595        pbundle->method_elm = method_elm;
 596        pbundle->method_key = attrs_iter.index;
 597        pbundle->bundle.ufile = ufile;
 598        pbundle->bundle.context = NULL; /* only valid if bundle has uobject */
 599        pbundle->radix = &uapi->radix;
 600        pbundle->radix_slots = slot;
 601        pbundle->radix_slots_len = radix_tree_chunk_size(&attrs_iter);
 602        pbundle->user_attrs = user_attrs;
 603
 604        pbundle->internal_used = ALIGN(pbundle->method_elm->key_bitmap_len *
 605                                               sizeof(*pbundle->bundle.attrs),
 606                                       sizeof(*pbundle->internal_buffer));
 607        memset(pbundle->bundle.attr_present, 0,
 608               sizeof(pbundle->bundle.attr_present));
 609        memset(pbundle->uobj_finalize, 0, sizeof(pbundle->uobj_finalize));
 610        memset(pbundle->spec_finalize, 0, sizeof(pbundle->spec_finalize));
 611
 612        ret = ib_uverbs_run_method(pbundle, hdr->num_attrs);
 613        destroy_ret = bundle_destroy(pbundle, ret == 0);
 614        if (unlikely(destroy_ret && !ret))
 615                return destroy_ret;
 616
 617        return ret;
 618}
 619
 620long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 621{
 622        struct ib_uverbs_file *file = filp->private_data;
 623        struct ib_uverbs_ioctl_hdr __user *user_hdr =
 624                (struct ib_uverbs_ioctl_hdr __user *)arg;
 625        struct ib_uverbs_ioctl_hdr hdr;
 626        int srcu_key;
 627        int err;
 628
 629        if (unlikely(cmd != RDMA_VERBS_IOCTL))
 630                return -ENOIOCTLCMD;
 631
 632        err = copy_from_user(&hdr, user_hdr, sizeof(hdr));
 633        if (err)
 634                return -EFAULT;
 635
 636        if (hdr.length > PAGE_SIZE ||
 637            hdr.length != struct_size(&hdr, attrs, hdr.num_attrs))
 638                return -EINVAL;
 639
 640        if (hdr.reserved1 || hdr.reserved2)
 641                return -EPROTONOSUPPORT;
 642
 643        srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
 644        err = ib_uverbs_cmd_verbs(file, &hdr, user_hdr->attrs);
 645        srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
 646        return err;
 647}
 648
 649int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
 650                       size_t idx, u64 allowed_bits)
 651{
 652        const struct uverbs_attr *attr;
 653        u64 flags;
 654
 655        attr = uverbs_attr_get(attrs_bundle, idx);
 656        /* Missing attribute means 0 flags */
 657        if (IS_ERR(attr)) {
 658                *to = 0;
 659                return 0;
 660        }
 661
 662        /*
 663         * New userspace code should use 8 bytes to pass flags, but we
 664         * transparently support old userspaces that were using 4 bytes as
 665         * well.
 666         */
 667        if (attr->ptr_attr.len == 8)
 668                flags = attr->ptr_attr.data;
 669        else if (attr->ptr_attr.len == 4)
 670                flags = *(u32 *)&attr->ptr_attr.data;
 671        else
 672                return -EINVAL;
 673
 674        if (flags & ~allowed_bits)
 675                return -EINVAL;
 676
 677        *to = flags;
 678        return 0;
 679}
 680EXPORT_SYMBOL(uverbs_get_flags64);
 681
 682int uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle,
 683                       size_t idx, u64 allowed_bits)
 684{
 685        u64 flags;
 686        int ret;
 687
 688        ret = uverbs_get_flags64(&flags, attrs_bundle, idx, allowed_bits);
 689        if (ret)
 690                return ret;
 691
 692        if (flags > U32_MAX)
 693                return -EINVAL;
 694        *to = flags;
 695
 696        return 0;
 697}
 698EXPORT_SYMBOL(uverbs_get_flags32);
 699
 700/*
 701 * Fill a ib_udata struct (core or uhw) using the given attribute IDs.
 702 * This is primarily used to convert the UVERBS_ATTR_UHW() into the
 703 * ib_udata format used by the drivers.
 704 */
 705void uverbs_fill_udata(struct uverbs_attr_bundle *bundle,
 706                       struct ib_udata *udata, unsigned int attr_in,
 707                       unsigned int attr_out)
 708{
 709        struct bundle_priv *pbundle =
 710                container_of(bundle, struct bundle_priv, bundle);
 711        const struct uverbs_attr *in =
 712                uverbs_attr_get(&pbundle->bundle, attr_in);
 713        const struct uverbs_attr *out =
 714                uverbs_attr_get(&pbundle->bundle, attr_out);
 715
 716        if (!IS_ERR(in)) {
 717                udata->inlen = in->ptr_attr.len;
 718                if (uverbs_attr_ptr_is_inline(in))
 719                        udata->inbuf =
 720                                &pbundle->user_attrs[in->ptr_attr.uattr_idx]
 721                                         .data;
 722                else
 723                        udata->inbuf = u64_to_user_ptr(in->ptr_attr.data);
 724        } else {
 725                udata->inbuf = NULL;
 726                udata->inlen = 0;
 727        }
 728
 729        if (!IS_ERR(out)) {
 730                udata->outbuf = u64_to_user_ptr(out->ptr_attr.data);
 731                udata->outlen = out->ptr_attr.len;
 732        } else {
 733                udata->outbuf = NULL;
 734                udata->outlen = 0;
 735        }
 736}
 737
 738int uverbs_copy_to(const struct uverbs_attr_bundle *bundle, size_t idx,
 739                   const void *from, size_t size)
 740{
 741        const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx);
 742        size_t min_size;
 743
 744        if (IS_ERR(attr))
 745                return PTR_ERR(attr);
 746
 747        min_size = min_t(size_t, attr->ptr_attr.len, size);
 748        if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size))
 749                return -EFAULT;
 750
 751        return uverbs_set_output(bundle, attr);
 752}
 753EXPORT_SYMBOL(uverbs_copy_to);
 754
 755
 756/*
 757 * This is only used if the caller has directly used copy_to_use to write the
 758 * data.  It signals to user space that the buffer is filled in.
 759 */
 760int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx)
 761{
 762        const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx);
 763
 764        if (IS_ERR(attr))
 765                return PTR_ERR(attr);
 766
 767        return uverbs_set_output(bundle, attr);
 768}
 769
 770int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle,
 771                      size_t idx, s64 lower_bound, u64 upper_bound,
 772                      s64  *def_val)
 773{
 774        const struct uverbs_attr *attr;
 775
 776        attr = uverbs_attr_get(attrs_bundle, idx);
 777        if (IS_ERR(attr)) {
 778                if ((PTR_ERR(attr) != -ENOENT) || !def_val)
 779                        return PTR_ERR(attr);
 780
 781                *to = *def_val;
 782        } else {
 783                *to = attr->ptr_attr.data;
 784        }
 785
 786        if (*to < lower_bound || (*to > 0 && (u64)*to > upper_bound))
 787                return -EINVAL;
 788
 789        return 0;
 790}
 791EXPORT_SYMBOL(_uverbs_get_const);
 792
 793int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
 794                                  size_t idx, const void *from, size_t size)
 795{
 796        const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx);
 797
 798        if (size < attr->ptr_attr.len) {
 799                if (clear_user(u64_to_user_ptr(attr->ptr_attr.data) + size,
 800                               attr->ptr_attr.len - size))
 801                        return -EFAULT;
 802        }
 803        return uverbs_copy_to(bundle, idx, from, size);
 804}
 805