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 41 /* 42 * ======================================= 43 * Verbs action specifications 44 * ======================================= 45 */ 46 47 enum uverbs_attr_type { 48 UVERBS_ATTR_TYPE_NA, 49 UVERBS_ATTR_TYPE_PTR_IN, 50 UVERBS_ATTR_TYPE_PTR_OUT, 51 UVERBS_ATTR_TYPE_IDR, 52 UVERBS_ATTR_TYPE_FD, 53 }; 54 55 enum uverbs_obj_access { 56 UVERBS_ACCESS_READ, 57 UVERBS_ACCESS_WRITE, 58 UVERBS_ACCESS_NEW, 59 UVERBS_ACCESS_DESTROY 60 }; 61 62 enum { 63 UVERBS_ATTR_SPEC_F_MANDATORY = 1U << 0, 64 /* Support extending attributes by length */ 65 UVERBS_ATTR_SPEC_F_MIN_SZ = 1U << 1, 66 }; 67 68 struct uverbs_attr_spec { 69 enum uverbs_attr_type type; 70 union { 71 u16 len; 72 struct { 73 /* 74 * higher bits mean the namespace and lower bits mean 75 * the type id within the namespace. 76 */ 77 u16 obj_type; 78 u8 access; 79 } obj; 80 }; 81 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */ 82 u8 flags; 83 }; 84 85 struct uverbs_attr_spec_hash { 86 size_t num_attrs; 87 unsigned long *mandatory_attrs_bitmask; 88 struct uverbs_attr_spec attrs[0]; 89 }; 90 91 struct uverbs_attr_bundle; 92 struct ib_uverbs_file; 93 94 enum { 95 /* 96 * Action marked with this flag creates a context (or root for all 97 * objects). 98 */ 99 UVERBS_ACTION_FLAG_CREATE_ROOT = 1U << 0, 100 }; 101 102 struct uverbs_method_spec { 103 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ 104 u32 flags; 105 size_t num_buckets; 106 size_t num_child_attrs; 107 int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, 108 struct uverbs_attr_bundle *ctx); 109 struct uverbs_attr_spec_hash *attr_buckets[0]; 110 }; 111 112 struct uverbs_method_spec_hash { 113 size_t num_methods; 114 struct uverbs_method_spec *methods[0]; 115 }; 116 117 struct uverbs_object_spec { 118 const struct uverbs_obj_type *type_attrs; 119 size_t num_buckets; 120 struct uverbs_method_spec_hash *method_buckets[0]; 121 }; 122 123 struct uverbs_object_spec_hash { 124 size_t num_objects; 125 struct uverbs_object_spec *objects[0]; 126 }; 127 128 struct uverbs_root_spec { 129 size_t num_buckets; 130 struct uverbs_object_spec_hash *object_buckets[0]; 131 }; 132 133 /* 134 * ======================================= 135 * Verbs definitions 136 * ======================================= 137 */ 138 139 struct uverbs_attr_def { 140 u16 id; 141 struct uverbs_attr_spec attr; 142 }; 143 144 struct uverbs_method_def { 145 u16 id; 146 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ 147 u32 flags; 148 size_t num_attrs; 149 const struct uverbs_attr_def * const (*attrs)[]; 150 int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, 151 struct uverbs_attr_bundle *ctx); 152 }; 153 154 struct uverbs_object_def { 155 u16 id; 156 const struct uverbs_obj_type *type_attrs; 157 size_t num_methods; 158 const struct uverbs_method_def * const (*methods)[]; 159 }; 160 161 struct uverbs_object_tree_def { 162 size_t num_objects; 163 const struct uverbs_object_def * const (*objects)[]; 164 }; 165 166 #define UA_FLAGS(_flags) .flags = _flags 167 #define __UVERBS_ATTR0(_id, _len, _type, ...) \ 168 ((const struct uverbs_attr_def) \ 169 {.id = _id, .attr = {.type = _type, {.len = _len}, .flags = 0, } }) 170 #define __UVERBS_ATTR1(_id, _len, _type, _flags) \ 171 ((const struct uverbs_attr_def) \ 172 {.id = _id, .attr = {.type = _type, {.len = _len}, _flags, } }) 173 #define __UVERBS_ATTR(_id, _len, _type, _flags, _n, ...) \ 174 __UVERBS_ATTR##_n(_id, _len, _type, _flags) 175 /* 176 * In new compiler, UVERBS_ATTR could be simplified by declaring it as 177 * [_id] = {.type = _type, .len = _len, ##__VA_ARGS__} 178 * But since we support older compilers too, we need the more complex code. 179 */ 180 #define UVERBS_ATTR(_id, _len, _type, ...) \ 181 __UVERBS_ATTR(_id, _len, _type, ##__VA_ARGS__, 1, 0) 182 #define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...) \ 183 UVERBS_ATTR(_id, _len, UVERBS_ATTR_TYPE_PTR_IN, ##__VA_ARGS__) 184 /* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */ 185 #define UVERBS_ATTR_PTR_IN(_id, _type, ...) \ 186 UVERBS_ATTR_PTR_IN_SZ(_id, sizeof(_type), ##__VA_ARGS__) 187 #define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...) \ 188 UVERBS_ATTR(_id, _len, UVERBS_ATTR_TYPE_PTR_OUT, ##__VA_ARGS__) 189 #define UVERBS_ATTR_PTR_OUT(_id, _type, ...) \ 190 UVERBS_ATTR_PTR_OUT_SZ(_id, sizeof(_type), ##__VA_ARGS__) 191 192 /* 193 * In new compiler, UVERBS_ATTR_IDR (and FD) could be simplified by declaring 194 * it as 195 * {.id = _id, \ 196 * .attr {.type = __obj_class, \ 197 * .obj = {.obj_type = _idr_type, \ 198 * .access = _access \ 199 * }, ##__VA_ARGS__ } } 200 * But since we support older compilers too, we need the more complex code. 201 */ 202 #define ___UVERBS_ATTR_OBJ0(_id, _obj_class, _obj_type, _access, ...)\ 203 ((const struct uverbs_attr_def) \ 204 {.id = _id, \ 205 .attr = {.type = _obj_class, \ 206 {.obj = {.obj_type = _obj_type, .access = _access } },\ 207 .flags = 0} }) 208 #define ___UVERBS_ATTR_OBJ1(_id, _obj_class, _obj_type, _access, _flags)\ 209 ((const struct uverbs_attr_def) \ 210 {.id = _id, \ 211 .attr = {.type = _obj_class, \ 212 {.obj = {.obj_type = _obj_type, .access = _access} }, \ 213 _flags} }) 214 #define ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, _flags, \ 215 _n, ...) \ 216 ___UVERBS_ATTR_OBJ##_n(_id, _obj_class, _obj_type, _access, _flags) 217 #define __UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, ...) \ 218 ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, \ 219 ##__VA_ARGS__, 1, 0) 220 #define UVERBS_ATTR_IDR(_id, _idr_type, _access, ...) \ 221 __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_IDR, _idr_type, _access,\ 222 ##__VA_ARGS__) 223 #define UVERBS_ATTR_FD(_id, _fd_type, _access, ...) \ 224 __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_FD, _fd_type, \ 225 (_access) + BUILD_BUG_ON_ZERO( \ 226 (_access) != UVERBS_ACCESS_NEW && \ 227 (_access) != UVERBS_ACCESS_READ), \ 228 ##__VA_ARGS__) 229 #define DECLARE_UVERBS_ATTR_SPEC(_name, ...) \ 230 const struct uverbs_attr_def _name = __VA_ARGS__ 231 232 #define _UVERBS_METHOD_ATTRS_SZ(...) \ 233 (sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\ 234 sizeof(const struct uverbs_attr_def *)) 235 #define _UVERBS_METHOD(_id, _handler, _flags, ...) \ 236 ((const struct uverbs_method_def) { \ 237 .id = _id, \ 238 .flags = _flags, \ 239 .handler = _handler, \ 240 .num_attrs = _UVERBS_METHOD_ATTRS_SZ(__VA_ARGS__), \ 241 .attrs = &(const struct uverbs_attr_def * const []){__VA_ARGS__} }) 242 #define DECLARE_UVERBS_METHOD(_name, _id, _handler, ...) \ 243 const struct uverbs_method_def _name = \ 244 _UVERBS_METHOD(_id, _handler, 0, ##__VA_ARGS__) 245 #define DECLARE_UVERBS_CTX_METHOD(_name, _id, _handler, _flags, ...) \ 246 const struct uverbs_method_def _name = \ 247 _UVERBS_METHOD(_id, _handler, \ 248 UVERBS_ACTION_FLAG_CREATE_ROOT, \ 249 ##__VA_ARGS__) 250 #define _UVERBS_OBJECT_METHODS_SZ(...) \ 251 (sizeof((const struct uverbs_method_def * const []){__VA_ARGS__}) / \ 252 sizeof(const struct uverbs_method_def *)) 253 #define _UVERBS_OBJECT(_id, _type_attrs, ...) \ 254 ((const struct uverbs_object_def) { \ 255 .id = _id, \ 256 .type_attrs = _type_attrs, \ 257 .num_methods = _UVERBS_OBJECT_METHODS_SZ(__VA_ARGS__), \ 258 .methods = &(const struct uverbs_method_def * const []){__VA_ARGS__} }) 259 #define DECLARE_UVERBS_OBJECT(_name, _id, _type_attrs, ...) \ 260 const struct uverbs_object_def _name = \ 261 _UVERBS_OBJECT(_id, _type_attrs, ##__VA_ARGS__) 262 #define _UVERBS_TREE_OBJECTS_SZ(...) \ 263 (sizeof((const struct uverbs_object_def * const []){__VA_ARGS__}) / \ 264 sizeof(const struct uverbs_object_def *)) 265 #define _UVERBS_OBJECT_TREE(...) \ 266 ((const struct uverbs_object_tree_def) { \ 267 .num_objects = _UVERBS_TREE_OBJECTS_SZ(__VA_ARGS__), \ 268 .objects = &(const struct uverbs_object_def * const []){__VA_ARGS__} }) 269 #define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \ 270 const struct uverbs_object_tree_def _name = \ 271 _UVERBS_OBJECT_TREE(__VA_ARGS__) 272 273 /* ================================================= 274 * Parsing infrastructure 275 * ================================================= 276 */ 277 278 struct uverbs_ptr_attr { 279 u64 data; 280 u16 len; 281 /* Combination of bits from enum UVERBS_ATTR_F_XXXX */ 282 u16 flags; 283 }; 284 285 struct uverbs_obj_attr { 286 /* pointer to the kernel descriptor -> type, access, etc */ 287 const struct uverbs_obj_type *type; 288 struct ib_uobject *uobject; 289 /* fd or id in idr of this object */ 290 int id; 291 }; 292 293 struct uverbs_attr { 294 /* 295 * pointer to the user-space given attribute, in order to write the 296 * new uobject's id or update flags. 297 */ 298 struct ib_uverbs_attr __user *uattr; 299 union { 300 struct uverbs_ptr_attr ptr_attr; 301 struct uverbs_obj_attr obj_attr; 302 }; 303 }; 304 305 struct uverbs_attr_bundle_hash { 306 /* if bit i is set, it means attrs[i] contains valid information */ 307 unsigned long *valid_bitmap; 308 size_t num_attrs; 309 /* 310 * arrays of attributes, each element corresponds to the specification 311 * of the attribute in the same index. 312 */ 313 struct uverbs_attr *attrs; 314 }; 315 316 struct uverbs_attr_bundle { 317 size_t num_buckets; 318 struct uverbs_attr_bundle_hash hash[]; 319 }; 320 321 static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash, 322 unsigned int idx) 323 { 324 return test_bit(idx, attrs_hash->valid_bitmap); 325 } 326 327 static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle, 328 unsigned int idx) 329 { 330 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; 331 332 if (attrs_bundle->num_buckets <= idx_bucket) 333 return false; 334 335 return uverbs_attr_is_valid_in_hash(&attrs_bundle->hash[idx_bucket], 336 idx & ~UVERBS_ID_NS_MASK); 337 } 338 339 static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle, 340 u16 idx) 341 { 342 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; 343 344 if (!uverbs_attr_is_valid(attrs_bundle, idx)) 345 return ERR_PTR(-ENOENT); 346 347 return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK]; 348 } 349 350 static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, 351 size_t idx, const void *from, size_t size) 352 { 353 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 354 u16 flags; 355 size_t min_size; 356 357 if (IS_ERR(attr)) 358 return PTR_ERR(attr); 359 360 min_size = min_t(size_t, attr->ptr_attr.len, size); 361 if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size)) 362 return -EFAULT; 363 364 flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT; 365 if (put_user(flags, &attr->uattr->flags)) 366 return -EFAULT; 367 368 return 0; 369 } 370 371 static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr) 372 { 373 return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data); 374 } 375 376 static inline int _uverbs_copy_from(void *to, 377 const struct uverbs_attr_bundle *attrs_bundle, 378 size_t idx, 379 size_t size) 380 { 381 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 382 383 if (IS_ERR(attr)) 384 return PTR_ERR(attr); 385 386 /* 387 * Validation ensures attr->ptr_attr.len >= size. If the caller is 388 * using UVERBS_ATTR_SPEC_F_MIN_SZ then it must call copy_from with 389 * the right size. 390 */ 391 if (unlikely(size < attr->ptr_attr.len)) 392 return -EINVAL; 393 394 if (uverbs_attr_ptr_is_inline(attr)) 395 memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len); 396 else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data), 397 attr->ptr_attr.len)) 398 return -EFAULT; 399 400 return 0; 401 } 402 403 #define uverbs_copy_from(to, attrs_bundle, idx) \ 404 _uverbs_copy_from(to, attrs_bundle, idx, sizeof(*to)) 405 406 /* ================================================= 407 * Definitions -> Specs infrastructure 408 * ================================================= 409 */ 410 411 /* 412 * uverbs_alloc_spec_tree - Merges different common and driver specific feature 413 * into one parsing tree that every uverbs command will be parsed upon. 414 * 415 * @num_trees: Number of trees in the array @trees. 416 * @trees: Array of pointers to tree root definitions to merge. Each such tree 417 * possibly contains objects, methods and attributes definitions. 418 * 419 * Returns: 420 * uverbs_root_spec *: The root of the merged parsing tree. 421 * On error, we return an error code. Error is checked via IS_ERR. 422 * 423 * The following merges could take place: 424 * a. Two trees representing the same method with different handler 425 * -> We take the handler of the tree that its handler != NULL 426 * and its index in the trees array is greater. The incentive for that 427 * is that developers are expected to first merge common trees and then 428 * merge trees that gives specialized the behaviour. 429 * b. Two trees representing the same object with different 430 * type_attrs (struct uverbs_obj_type): 431 * -> We take the type_attrs of the tree that its type_attr != NULL 432 * and its index in the trees array is greater. This could be used 433 * in order to override the free function, allocation size, etc. 434 * c. Two trees representing the same method attribute (same id but possibly 435 * different attributes): 436 * -> ERROR (-ENOENT), we believe that's not the programmer's intent. 437 * 438 * An object without any methods is considered invalid and will abort the 439 * function with -ENOENT error. 440 */ 441 #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) 442 struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, 443 const struct uverbs_object_tree_def **trees); 444 void uverbs_free_spec_tree(struct uverbs_root_spec *root); 445 #else 446 static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, 447 const struct uverbs_object_tree_def **trees) 448 { 449 return NULL; 450 } 451 452 static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root) 453 { 454 } 455 #endif 456 457 #endif 458