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 union { 280 u64 data; 281 void __user *ptr; 282 }; 283 u16 len; 284 /* Combination of bits from enum UVERBS_ATTR_F_XXXX */ 285 u16 flags; 286 }; 287 288 struct uverbs_obj_attr { 289 /* pointer to the kernel descriptor -> type, access, etc */ 290 const struct uverbs_obj_type *type; 291 struct ib_uobject *uobject; 292 /* fd or id in idr of this object */ 293 int id; 294 }; 295 296 struct uverbs_attr { 297 /* 298 * pointer to the user-space given attribute, in order to write the 299 * new uobject's id or update flags. 300 */ 301 struct ib_uverbs_attr __user *uattr; 302 union { 303 struct uverbs_ptr_attr ptr_attr; 304 struct uverbs_obj_attr obj_attr; 305 }; 306 }; 307 308 struct uverbs_attr_bundle_hash { 309 /* if bit i is set, it means attrs[i] contains valid information */ 310 unsigned long *valid_bitmap; 311 size_t num_attrs; 312 /* 313 * arrays of attributes, each element corresponds to the specification 314 * of the attribute in the same index. 315 */ 316 struct uverbs_attr *attrs; 317 }; 318 319 struct uverbs_attr_bundle { 320 size_t num_buckets; 321 struct uverbs_attr_bundle_hash hash[]; 322 }; 323 324 static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash, 325 unsigned int idx) 326 { 327 return test_bit(idx, attrs_hash->valid_bitmap); 328 } 329 330 static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle, 331 unsigned int idx) 332 { 333 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; 334 335 if (attrs_bundle->num_buckets <= idx_bucket) 336 return false; 337 338 return uverbs_attr_is_valid_in_hash(&attrs_bundle->hash[idx_bucket], 339 idx & ~UVERBS_ID_NS_MASK); 340 } 341 342 static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle, 343 u16 idx) 344 { 345 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; 346 347 if (!uverbs_attr_is_valid(attrs_bundle, idx)) 348 return ERR_PTR(-ENOENT); 349 350 return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK]; 351 } 352 353 static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, 354 size_t idx, const void *from) 355 { 356 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 357 u16 flags; 358 359 if (IS_ERR(attr)) 360 return PTR_ERR(attr); 361 362 flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT; 363 return (!copy_to_user(attr->ptr_attr.ptr, from, attr->ptr_attr.len) && 364 !put_user(flags, &attr->uattr->flags)) ? 0 : -EFAULT; 365 } 366 367 static inline int _uverbs_copy_from(void *to, size_t to_size, 368 const struct uverbs_attr_bundle *attrs_bundle, 369 size_t idx) 370 { 371 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); 372 373 if (IS_ERR(attr)) 374 return PTR_ERR(attr); 375 376 if (to_size <= sizeof(((struct ib_uverbs_attr *)0)->data)) 377 memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len); 378 else if (copy_from_user(to, attr->ptr_attr.ptr, attr->ptr_attr.len)) 379 return -EFAULT; 380 381 return 0; 382 } 383 384 #define uverbs_copy_from(to, attrs_bundle, idx) \ 385 _uverbs_copy_from(to, sizeof(*(to)), attrs_bundle, idx) 386 387 /* ================================================= 388 * Definitions -> Specs infrastructure 389 * ================================================= 390 */ 391 392 /* 393 * uverbs_alloc_spec_tree - Merges different common and driver specific feature 394 * into one parsing tree that every uverbs command will be parsed upon. 395 * 396 * @num_trees: Number of trees in the array @trees. 397 * @trees: Array of pointers to tree root definitions to merge. Each such tree 398 * possibly contains objects, methods and attributes definitions. 399 * 400 * Returns: 401 * uverbs_root_spec *: The root of the merged parsing tree. 402 * On error, we return an error code. Error is checked via IS_ERR. 403 * 404 * The following merges could take place: 405 * a. Two trees representing the same method with different handler 406 * -> We take the handler of the tree that its handler != NULL 407 * and its index in the trees array is greater. The incentive for that 408 * is that developers are expected to first merge common trees and then 409 * merge trees that gives specialized the behaviour. 410 * b. Two trees representing the same object with different 411 * type_attrs (struct uverbs_obj_type): 412 * -> We take the type_attrs of the tree that its type_attr != NULL 413 * and its index in the trees array is greater. This could be used 414 * in order to override the free function, allocation size, etc. 415 * c. Two trees representing the same method attribute (same id but possibly 416 * different attributes): 417 * -> ERROR (-ENOENT), we believe that's not the programmer's intent. 418 * 419 * An object without any methods is considered invalid and will abort the 420 * function with -ENOENT error. 421 */ 422 #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) 423 struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, 424 const struct uverbs_object_tree_def **trees); 425 void uverbs_free_spec_tree(struct uverbs_root_spec *root); 426 #else 427 static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, 428 const struct uverbs_object_tree_def **trees) 429 { 430 return NULL; 431 } 432 433 static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root) 434 { 435 } 436 #endif 437 438 #endif 439