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