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 #ifndef _UVERBS_IOCTL_ 34 #define _UVERBS_IOCTL_ 35 36 #include <rdma/uverbs_types.h> 37 #include <linux/uaccess.h> 38 #include <rdma/rdma_user_ioctl.h> 39 #include <rdma/ib_user_ioctl_verbs.h> 40 #include <rdma/ib_user_ioctl_cmds.h> 41 42 /* 43 * ======================================= 44 * Verbs action specifications 45 * ======================================= 46 */ 47 48 enum uverbs_attr_type { 49 UVERBS_ATTR_TYPE_NA, 50 UVERBS_ATTR_TYPE_PTR_IN, 51 UVERBS_ATTR_TYPE_PTR_OUT, 52 UVERBS_ATTR_TYPE_IDR, 53 UVERBS_ATTR_TYPE_FD, 54 UVERBS_ATTR_TYPE_ENUM_IN, 55 UVERBS_ATTR_TYPE_IDRS_ARRAY, 56 }; 57 58 enum uverbs_obj_access { 59 UVERBS_ACCESS_READ, 60 UVERBS_ACCESS_WRITE, 61 UVERBS_ACCESS_NEW, 62 UVERBS_ACCESS_DESTROY 63 }; 64 65 /* Specification of a single attribute inside the ioctl message */ 66 /* good size 16 */ 67 struct uverbs_attr_spec { 68 u8 type; 69 70 /* 71 * Support extending attributes by length. Allow the user to provide 72 * more bytes than ptr.len, but check that everything after is zero'd 73 * by the user. 74 */ 75 u8 zero_trailing:1; 76 /* 77 * Valid only for PTR_IN. Allocate and copy the data inside 78 * the parser 79 */ 80 u8 alloc_and_copy:1; 81 u8 mandatory:1; 82 83 union { 84 struct { 85 /* Current known size to kernel */ 86 u16 len; 87 /* User isn't allowed to provide something < min_len */ 88 u16 min_len; 89 } ptr; 90 91 struct { 92 /* 93 * higher bits mean the namespace and lower bits mean 94 * the type id within the namespace. 95 */ 96 u16 obj_type; 97 u8 access; 98 } obj; 99 100 struct { 101 u8 num_elems; 102 } enum_def; 103 } u; 104 105 /* This weird split lets us remove some padding */ 106 union { 107 struct { 108 /* 109 * The enum attribute can select one of the attributes 110 * contained in the ids array. Currently only PTR_IN 111 * attributes are supported in the ids array. 112 */ 113 const struct uverbs_attr_spec *ids; 114 } enum_def; 115 116 struct { 117 /* 118 * higher bits mean the namespace and lower bits mean 119 * the type id within the namespace. 120 */ 121 u16 obj_type; 122 u16 min_len; 123 u16 max_len; 124 u8 access; 125 } objs_arr; 126 } u2; 127 }; 128 129 /* 130 * Information about the API is loaded into a radix tree. For IOCTL we start 131 * with a tuple of: 132 * object_id, attr_id, method_id 133 * 134 * Which is a 48 bit value, with most of the bits guaranteed to be zero. Based 135 * on the current kernel support this is compressed into 16 bit key for the 136 * radix tree. Since this compression is entirely internal to the kernel the 137 * below limits can be revised if the kernel gains additional data. 138 * 139 * With 64 leafs per node this is a 3 level radix tree. 140 * 141 * The tree encodes multiple types, and uses a scheme where OBJ_ID,0,0 returns 142 * the object slot, and OBJ_ID,METH_ID,0 and returns the method slot. 143 */ 144 enum uapi_radix_data { 145 UVERBS_API_NS_FLAG = 1U << UVERBS_ID_NS_SHIFT, 146 147 UVERBS_API_ATTR_KEY_BITS = 6, 148 UVERBS_API_ATTR_KEY_MASK = GENMASK(UVERBS_API_ATTR_KEY_BITS - 1, 0), 149 UVERBS_API_ATTR_BKEY_LEN = (1 << UVERBS_API_ATTR_KEY_BITS) - 1, 150 151 UVERBS_API_METHOD_KEY_BITS = 5, 152 UVERBS_API_METHOD_KEY_SHIFT = UVERBS_API_ATTR_KEY_BITS, 153 UVERBS_API_METHOD_KEY_NUM_CORE = 24, 154 UVERBS_API_METHOD_KEY_NUM_DRIVER = (1 << UVERBS_API_METHOD_KEY_BITS) - 155 UVERBS_API_METHOD_KEY_NUM_CORE, 156 UVERBS_API_METHOD_KEY_MASK = GENMASK( 157 UVERBS_API_METHOD_KEY_BITS + UVERBS_API_METHOD_KEY_SHIFT - 1, 158 UVERBS_API_METHOD_KEY_SHIFT), 159 160 UVERBS_API_OBJ_KEY_BITS = 5, 161 UVERBS_API_OBJ_KEY_SHIFT = 162 UVERBS_API_METHOD_KEY_BITS + UVERBS_API_METHOD_KEY_SHIFT, 163 UVERBS_API_OBJ_KEY_NUM_CORE = 24, 164 UVERBS_API_OBJ_KEY_NUM_DRIVER = 165 (1 << UVERBS_API_OBJ_KEY_BITS) - UVERBS_API_OBJ_KEY_NUM_CORE, 166 UVERBS_API_OBJ_KEY_MASK = GENMASK(31, UVERBS_API_OBJ_KEY_SHIFT), 167 168 /* This id guaranteed to not exist in the radix tree */ 169 UVERBS_API_KEY_ERR = 0xFFFFFFFF, 170 }; 171 172 static inline __attribute_const__ u32 uapi_key_obj(u32 id) 173 { 174 if (id & UVERBS_API_NS_FLAG) { 175 id &= ~UVERBS_API_NS_FLAG; 176 if (id >= UVERBS_API_OBJ_KEY_NUM_DRIVER) 177 return UVERBS_API_KEY_ERR; 178 id = id + UVERBS_API_OBJ_KEY_NUM_CORE; 179 } else { 180 if (id >= UVERBS_API_OBJ_KEY_NUM_CORE) 181 return UVERBS_API_KEY_ERR; 182 } 183 184 return id << UVERBS_API_OBJ_KEY_SHIFT; 185 } 186 187 static inline __attribute_const__ bool uapi_key_is_object(u32 key) 188 { 189 return (key & ~UVERBS_API_OBJ_KEY_MASK) == 0; 190 } 191 192 static inline __attribute_const__ u32 uapi_key_ioctl_method(u32 id) 193 { 194 if (id & UVERBS_API_NS_FLAG) { 195 id &= ~UVERBS_API_NS_FLAG; 196 if (id >= UVERBS_API_METHOD_KEY_NUM_DRIVER) 197 return UVERBS_API_KEY_ERR; 198 id = id + UVERBS_API_METHOD_KEY_NUM_CORE; 199 } else { 200 id++; 201 if (id >= UVERBS_API_METHOD_KEY_NUM_CORE) 202 return UVERBS_API_KEY_ERR; 203 } 204 205 return id << UVERBS_API_METHOD_KEY_SHIFT; 206 } 207 208 static inline __attribute_const__ u32 uapi_key_attr_to_method(u32 attr_key) 209 { 210 return attr_key & 211 (UVERBS_API_OBJ_KEY_MASK | UVERBS_API_METHOD_KEY_MASK); 212 } 213 214 static inline __attribute_const__ bool uapi_key_is_ioctl_method(u32 key) 215 { 216 return (key & UVERBS_API_METHOD_KEY_MASK) != 0 && 217 (key & UVERBS_API_ATTR_KEY_MASK) == 0; 218 } 219 220 static inline __attribute_const__ u32 uapi_key_attrs_start(u32 ioctl_method_key) 221 { 222 /* 0 is the method slot itself */ 223 return ioctl_method_key + 1; 224 } 225 226 static inline __attribute_const__ u32 uapi_key_attr(u32 id) 227 { 228 /* 229 * The attr is designed to fit in the typical single radix tree node 230 * of 64 entries. Since allmost all methods have driver attributes we 231 * organize things so that the driver and core attributes interleave to 232 * reduce the length of the attributes array in typical cases. 233 */ 234 if (id & UVERBS_API_NS_FLAG) { 235 id &= ~UVERBS_API_NS_FLAG; 236 id++; 237 if (id >= 1 << (UVERBS_API_ATTR_KEY_BITS - 1)) 238 return UVERBS_API_KEY_ERR; 239 id = (id << 1) | 0; 240 } else { 241 if (id >= 1 << (UVERBS_API_ATTR_KEY_BITS - 1)) 242 return UVERBS_API_KEY_ERR; 243 id = (id << 1) | 1; 244 } 245 246 return id; 247 } 248 249 static inline __attribute_const__ bool uapi_key_is_attr(u32 key) 250 { 251 return (key & UVERBS_API_METHOD_KEY_MASK) != 0 && 252 (key & UVERBS_API_ATTR_KEY_MASK) != 0; 253 } 254 255 /* 256 * This returns a value in the range [0 to UVERBS_API_ATTR_BKEY_LEN), 257 * basically it undoes the reservation of 0 in the ID numbering. attr_key 258 * must already be masked with UVERBS_API_ATTR_KEY_MASK, or be the output of 259 * uapi_key_attr(). 260 */ 261 static inline __attribute_const__ u32 uapi_bkey_attr(u32 attr_key) 262 { 263 return attr_key - 1; 264 } 265 266 static inline __attribute_const__ u32 uapi_bkey_to_key_attr(u32 attr_bkey) 267 { 268 return attr_bkey + 1; 269 } 270 271 /* 272 * ======================================= 273 * Verbs definitions 274 * ======================================= 275 */ 276 277 struct uverbs_attr_def { 278 u16 id; 279 struct uverbs_attr_spec attr; 280 }; 281 282 struct uverbs_method_def { 283 u16 id; 284 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ 285 u32 flags; 286 size_t num_attrs; 287 const struct uverbs_attr_def * const (*attrs)[]; 288 int (*handler)(struct ib_uverbs_file *ufile, 289 struct uverbs_attr_bundle *ctx); 290 }; 291 292 struct uverbs_object_def { 293 u16 id; 294 const struct uverbs_obj_type *type_attrs; 295 size_t num_methods; 296 const struct uverbs_method_def * const (*methods)[]; 297 }; 298 299 struct uverbs_object_tree_def { 300 size_t num_objects; 301 const struct uverbs_object_def * const (*objects)[]; 302 }; 303 304 /* 305 * ======================================= 306 * Attribute Specifications 307 * ======================================= 308 */ 309 310 #define UVERBS_ATTR_SIZE(_min_len, _len) \ 311 .u.ptr.min_len = _min_len, .u.ptr.len = _len 312 313 #define UVERBS_ATTR_NO_DATA() UVERBS_ATTR_SIZE(0, 0) 314 315 /* 316 * Specifies a uapi structure that cannot be extended. The user must always 317 * supply the whole structure and nothing more. The structure must be declared 318 * in a header under include/uapi/rdma. 319 */ 320 #define UVERBS_ATTR_TYPE(_type) \ 321 .u.ptr.min_len = sizeof(_type), .u.ptr.len = sizeof(_type) 322 /* 323 * Specifies a uapi structure where the user must provide at least up to 324 * member 'last'. Anything after last and up until the end of the structure 325 * can be non-zero, anything longer than the end of the structure must be 326 * zero. The structure must be declared in a header under include/uapi/rdma. 327 */ 328 #define UVERBS_ATTR_STRUCT(_type, _last) \ 329 .zero_trailing = 1, \ 330 UVERBS_ATTR_SIZE(((uintptr_t)(&((_type *)0)->_last + 1)), \ 331 sizeof(_type)) 332 /* 333 * Specifies at least min_len bytes must be passed in, but the amount can be 334 * larger, up to the protocol maximum size. No check for zeroing is done. 335 */ 336 #define UVERBS_ATTR_MIN_SIZE(_min_len) UVERBS_ATTR_SIZE(_min_len, USHRT_MAX) 337 338 /* Must be used in the '...' of any UVERBS_ATTR */ 339 #define UA_ALLOC_AND_COPY .alloc_and_copy = 1 340 #define UA_MANDATORY .mandatory = 1 341 #define UA_OPTIONAL .mandatory = 0 342 343 /* 344 * min_len must be bigger than 0 and _max_len must be smaller than 4095. Only 345 * READ\WRITE accesses are supported. 346 */ 347 #define UVERBS_ATTR_IDRS_ARR(_attr_id, _idr_type, _access, _min_len, _max_len, \ 348 ...) \ 349 (&(const struct uverbs_attr_def){ \ 350 .id = (_attr_id) + \ 351 BUILD_BUG_ON_ZERO((_min_len) == 0 || \ 352 (_max_len) > \ 353 PAGE_SIZE / sizeof(void *) || \ 354 (_min_len) > (_max_len) || \ 355 (_access) == UVERBS_ACCESS_NEW || \ 356 (_access) == UVERBS_ACCESS_DESTROY), \ 357 .attr = { .type = UVERBS_ATTR_TYPE_IDRS_ARRAY, \ 358 .u2.objs_arr.obj_type = _idr_type, \ 359 .u2.objs_arr.access = _access, \ 360 .u2.objs_arr.min_len = _min_len, \ 361 .u2.objs_arr.max_len = _max_len, \ 362 __VA_ARGS__ } }) 363 364 #define UVERBS_ATTR_IDR(_attr_id, _idr_type, _access, ...) \ 365 (&(const struct uverbs_attr_def){ \ 366 .id = _attr_id, \ 367 .attr = { .type = UVERBS_ATTR_TYPE_IDR, \ 368 .u.obj.obj_type = _idr_type, \ 369 .u.obj.access = _access, \ 370 __VA_ARGS__ } }) 371 372 #define UVERBS_ATTR_FD(_attr_id, _fd_type, _access, ...) \ 373 (&(const struct uverbs_attr_def){ \ 374 .id = (_attr_id) + \ 375 BUILD_BUG_ON_ZERO((_access) != UVERBS_ACCESS_NEW && \ 376 (_access) != UVERBS_ACCESS_READ), \ 377 .attr = { .type = UVERBS_ATTR_TYPE_FD, \ 378 .u.obj.obj_type = _fd_type, \ 379 .u.obj.access = _access, \ 380 __VA_ARGS__ } }) 381 382 #define UVERBS_ATTR_PTR_IN(_attr_id, _type, ...) \ 383 (&(const struct uverbs_attr_def){ \ 384 .id = _attr_id, \ 385 .attr = { .type = UVERBS_ATTR_TYPE_PTR_IN, \ 386 _type, \ 387 __VA_ARGS__ } }) 388 389 #define UVERBS_ATTR_PTR_OUT(_attr_id, _type, ...) \ 390 (&(const struct uverbs_attr_def){ \ 391 .id = _attr_id, \ 392 .attr = { .type = UVERBS_ATTR_TYPE_PTR_OUT, \ 393 _type, \ 394 __VA_ARGS__ } }) 395 396 /* _enum_arry should be a 'static const union uverbs_attr_spec[]' */ 397 #define UVERBS_ATTR_ENUM_IN(_attr_id, _enum_arr, ...) \ 398 (&(const struct uverbs_attr_def){ \ 399 .id = _attr_id, \ 400 .attr = { .type = UVERBS_ATTR_TYPE_ENUM_IN, \ 401 .u2.enum_def.ids = _enum_arr, \ 402 .u.enum_def.num_elems = ARRAY_SIZE(_enum_arr), \ 403 __VA_ARGS__ }, \ 404 }) 405 406 /* An input value that is a member in the enum _enum_type. */ 407 #define UVERBS_ATTR_CONST_IN(_attr_id, _enum_type, ...) \ 408 UVERBS_ATTR_PTR_IN( \ 409 _attr_id, \ 410 UVERBS_ATTR_SIZE( \ 411 sizeof(u64) + BUILD_BUG_ON_ZERO(!sizeof(_enum_type)), \ 412 sizeof(u64)), \ 413 __VA_ARGS__) 414 415 /* 416 * An input value that is a bitwise combination of values of _enum_type. 417 * This permits the flag value to be passed as either a u32 or u64, it must 418 * be retrieved via uverbs_get_flag(). 419 */ 420 #define UVERBS_ATTR_FLAGS_IN(_attr_id, _enum_type, ...) \ 421 UVERBS_ATTR_PTR_IN( \ 422 _attr_id, \ 423 UVERBS_ATTR_SIZE(sizeof(u32) + BUILD_BUG_ON_ZERO( \ 424 !sizeof(_enum_type *)), \ 425 sizeof(u64)), \ 426 __VA_ARGS__) 427 428 /* 429 * This spec is used in order to pass information to the hardware driver in a 430 * legacy way. Every verb that could get driver specific data should get this 431 * spec. 432 */ 433 #define UVERBS_ATTR_UHW() \ 434 UVERBS_ATTR_PTR_IN(UVERBS_ATTR_UHW_IN, \ 435 UVERBS_ATTR_MIN_SIZE(0), \ 436 UA_OPTIONAL), \ 437 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_UHW_OUT, \ 438 UVERBS_ATTR_MIN_SIZE(0), \ 439 UA_OPTIONAL) 440 441 /* 442 * ======================================= 443 * Declaration helpers 444 * ======================================= 445 */ 446 447 #define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \ 448 static const struct uverbs_object_def *const _name##_ptr[] = { \ 449 __VA_ARGS__, \ 450 }; \ 451 static const struct uverbs_object_tree_def _name = { \ 452 .num_objects = ARRAY_SIZE(_name##_ptr), \ 453 .objects = &_name##_ptr, \ 454 } 455 456 /* ================================================= 457 * Parsing infrastructure 458 * ================================================= 459 */ 460 461 462 struct uverbs_ptr_attr { 463 /* 464 * If UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY is set then the 'ptr' is 465 * used. 466 */ 467 union { 468 void *ptr; 469 u64 data; 470 }; 471 u16 len; 472 u16 uattr_idx; 473 u8 enum_id; 474 }; 475 476 struct uverbs_obj_attr { 477 struct ib_uobject *uobject; 478 const struct uverbs_api_attr *attr_elm; 479 }; 480 481 struct uverbs_objs_arr_attr { 482 struct ib_uobject **uobjects; 483 u16 len; 484 }; 485 486 struct uverbs_attr { 487 union { 488 struct uverbs_ptr_attr ptr_attr; 489 struct uverbs_obj_attr obj_attr; 490 struct uverbs_objs_arr_attr objs_arr_attr; 491 }; 492 }; 493 494 struct uverbs_attr_bundle { 495 struct ib_uverbs_file *ufile; 496 DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN); 497 struct uverbs_attr attrs[]; 498 }; 499 500 static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle, 501 unsigned int idx) 502 { 503 return test_bit(uapi_bkey_attr(uapi_key_attr(idx)), 504 attrs_bundle->attr_present); 505 } 506 507 #define IS_UVERBS_COPY_ERR(_ret) ((_ret) && (_ret) != -ENOENT) 508 509 static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle, 510 u16 idx) 511 { 512 if (!uverbs_attr_is_valid(attrs_bundle, idx)) 513 return ERR_PTR(-ENOENT); 514 515 return &attrs_bundle->attrs[uapi_bkey_attr(uapi_key_attr(idx))]; 516 } 517 518 static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs_bundle, 519 u16 idx) 520 { 521 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 522 523 if (IS_ERR(attr)) 524 return PTR_ERR(attr); 525 526 return attr->ptr_attr.enum_id; 527 } 528 529 static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_bundle, 530 u16 idx) 531 { 532 const struct uverbs_attr *attr; 533 534 attr = uverbs_attr_get(attrs_bundle, idx); 535 if (IS_ERR(attr)) 536 return ERR_CAST(attr); 537 538 return attr->obj_attr.uobject->object; 539 } 540 541 static inline struct ib_uobject *uverbs_attr_get_uobject(const struct uverbs_attr_bundle *attrs_bundle, 542 u16 idx) 543 { 544 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 545 546 if (IS_ERR(attr)) 547 return ERR_CAST(attr); 548 549 return attr->obj_attr.uobject; 550 } 551 552 static inline int 553 uverbs_attr_get_len(const struct uverbs_attr_bundle *attrs_bundle, u16 idx) 554 { 555 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 556 557 if (IS_ERR(attr)) 558 return PTR_ERR(attr); 559 560 return attr->ptr_attr.len; 561 } 562 563 /** 564 * uverbs_attr_get_uobjs_arr() - Provides array's properties for attribute for 565 * UVERBS_ATTR_TYPE_IDRS_ARRAY. 566 * @arr: Returned pointer to array of pointers for uobjects or NULL if 567 * the attribute isn't provided. 568 * 569 * Return: The array length or 0 if no attribute was provided. 570 */ 571 static inline int uverbs_attr_get_uobjs_arr( 572 const struct uverbs_attr_bundle *attrs_bundle, u16 attr_idx, 573 struct ib_uobject ***arr) 574 { 575 const struct uverbs_attr *attr = 576 uverbs_attr_get(attrs_bundle, attr_idx); 577 578 if (IS_ERR(attr)) { 579 *arr = NULL; 580 return 0; 581 } 582 583 *arr = attr->objs_arr_attr.uobjects; 584 585 return attr->objs_arr_attr.len; 586 } 587 588 static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr) 589 { 590 return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data); 591 } 592 593 static inline void *uverbs_attr_get_alloced_ptr( 594 const struct uverbs_attr_bundle *attrs_bundle, u16 idx) 595 { 596 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 597 598 if (IS_ERR(attr)) 599 return (void *)attr; 600 601 return uverbs_attr_ptr_is_inline(attr) ? (void *)&attr->ptr_attr.data : 602 attr->ptr_attr.ptr; 603 } 604 605 static inline int _uverbs_copy_from(void *to, 606 const struct uverbs_attr_bundle *attrs_bundle, 607 size_t idx, 608 size_t size) 609 { 610 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 611 612 if (IS_ERR(attr)) 613 return PTR_ERR(attr); 614 615 /* 616 * Validation ensures attr->ptr_attr.len >= size. If the caller is 617 * using UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO then it must call 618 * uverbs_copy_from_or_zero. 619 */ 620 if (unlikely(size < attr->ptr_attr.len)) 621 return -EINVAL; 622 623 if (uverbs_attr_ptr_is_inline(attr)) 624 memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len); 625 else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data), 626 attr->ptr_attr.len)) 627 return -EFAULT; 628 629 return 0; 630 } 631 632 static inline int _uverbs_copy_from_or_zero(void *to, 633 const struct uverbs_attr_bundle *attrs_bundle, 634 size_t idx, 635 size_t size) 636 { 637 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 638 size_t min_size; 639 640 if (IS_ERR(attr)) 641 return PTR_ERR(attr); 642 643 min_size = min_t(size_t, size, attr->ptr_attr.len); 644 645 if (uverbs_attr_ptr_is_inline(attr)) 646 memcpy(to, &attr->ptr_attr.data, min_size); 647 else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data), 648 min_size)) 649 return -EFAULT; 650 651 if (size > min_size) 652 memset(to + min_size, 0, size - min_size); 653 654 return 0; 655 } 656 657 #define uverbs_copy_from(to, attrs_bundle, idx) \ 658 _uverbs_copy_from(to, attrs_bundle, idx, sizeof(*to)) 659 660 #define uverbs_copy_from_or_zero(to, attrs_bundle, idx) \ 661 _uverbs_copy_from_or_zero(to, attrs_bundle, idx, sizeof(*to)) 662 663 #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) 664 int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle, 665 size_t idx, u64 allowed_bits); 666 int uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle, 667 size_t idx, u64 allowed_bits); 668 int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, size_t idx, 669 const void *from, size_t size); 670 __malloc void *_uverbs_alloc(struct uverbs_attr_bundle *bundle, size_t size, 671 gfp_t flags); 672 673 static inline __malloc void *uverbs_alloc(struct uverbs_attr_bundle *bundle, 674 size_t size) 675 { 676 return _uverbs_alloc(bundle, size, GFP_KERNEL); 677 } 678 679 static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle, 680 size_t size) 681 { 682 return _uverbs_alloc(bundle, size, GFP_KERNEL | __GFP_ZERO); 683 } 684 int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle, 685 size_t idx, s64 lower_bound, u64 upper_bound, 686 s64 *def_val); 687 #else 688 static inline int 689 uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle, 690 size_t idx, u64 allowed_bits) 691 { 692 return -EINVAL; 693 } 694 static inline int 695 uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle, 696 size_t idx, u64 allowed_bits) 697 { 698 return -EINVAL; 699 } 700 static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, 701 size_t idx, const void *from, size_t size) 702 { 703 return -EINVAL; 704 } 705 static inline __malloc void *uverbs_alloc(struct uverbs_attr_bundle *bundle, 706 size_t size) 707 { 708 return ERR_PTR(-EINVAL); 709 } 710 static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle, 711 size_t size) 712 { 713 return ERR_PTR(-EINVAL); 714 } 715 static inline int 716 _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle, 717 size_t idx, s64 lower_bound, u64 upper_bound, 718 s64 *def_val) 719 { 720 return -EINVAL; 721 } 722 #endif 723 724 #define uverbs_get_const(_to, _attrs_bundle, _idx) \ 725 ({ \ 726 s64 _val; \ 727 int _ret = _uverbs_get_const(&_val, _attrs_bundle, _idx, \ 728 type_min(typeof(*_to)), \ 729 type_max(typeof(*_to)), NULL); \ 730 (*_to) = _val; \ 731 _ret; \ 732 }) 733 734 #define uverbs_get_const_default(_to, _attrs_bundle, _idx, _default) \ 735 ({ \ 736 s64 _val; \ 737 s64 _def_val = _default; \ 738 int _ret = \ 739 _uverbs_get_const(&_val, _attrs_bundle, _idx, \ 740 type_min(typeof(*_to)), \ 741 type_max(typeof(*_to)), &_def_val); \ 742 (*_to) = _val; \ 743 _ret; \ 744 }) 745 #endif 746