2 * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
33 #ifndef _UVERBS_IOCTL_
34 #define _UVERBS_IOCTL_
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>
43 * =======================================
44 * Verbs action specifications
45 * =======================================
48 enum uverbs_attr_type {
50 UVERBS_ATTR_TYPE_PTR_IN,
51 UVERBS_ATTR_TYPE_PTR_OUT,
54 UVERBS_ATTR_TYPE_ENUM_IN,
57 enum uverbs_obj_access {
65 UVERBS_ATTR_SPEC_F_MANDATORY = 1U << 0,
66 /* Support extending attributes by length, validate all unknown size == zero */
67 UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO = 1U << 1,
70 /* Specification of a single attribute inside the ioctl message */
71 struct uverbs_attr_spec {
73 /* Header shared by all following union members - to reduce space. */
75 enum uverbs_attr_type type;
76 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
80 enum uverbs_attr_type type;
81 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
83 /* Current known size to kernel */
85 /* User isn't allowed to provide something < min_len */
89 enum uverbs_attr_type type;
90 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
93 * higher bits mean the namespace and lower bits mean
94 * the type id within the namespace.
100 enum uverbs_attr_type type;
101 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
105 * The enum attribute can select one of the attributes
106 * contained in the ids array. Currently only PTR_IN
107 * attributes are supported in the ids array.
109 const struct uverbs_attr_spec *ids;
114 struct uverbs_attr_spec_hash {
116 unsigned long *mandatory_attrs_bitmask;
117 struct uverbs_attr_spec attrs[0];
120 struct uverbs_attr_bundle;
121 struct ib_uverbs_file;
125 * Action marked with this flag creates a context (or root for all
128 UVERBS_ACTION_FLAG_CREATE_ROOT = 1U << 0,
131 struct uverbs_method_spec {
132 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
135 size_t num_child_attrs;
136 int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile,
137 struct uverbs_attr_bundle *ctx);
138 struct uverbs_attr_spec_hash *attr_buckets[0];
141 struct uverbs_method_spec_hash {
143 struct uverbs_method_spec *methods[0];
146 struct uverbs_object_spec {
147 const struct uverbs_obj_type *type_attrs;
149 struct uverbs_method_spec_hash *method_buckets[0];
152 struct uverbs_object_spec_hash {
154 struct uverbs_object_spec *objects[0];
157 struct uverbs_root_spec {
159 struct uverbs_object_spec_hash *object_buckets[0];
163 * =======================================
165 * =======================================
168 struct uverbs_attr_def {
170 struct uverbs_attr_spec attr;
173 struct uverbs_method_def {
175 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
178 const struct uverbs_attr_def * const (*attrs)[];
179 int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile,
180 struct uverbs_attr_bundle *ctx);
183 struct uverbs_object_def {
185 const struct uverbs_obj_type *type_attrs;
187 const struct uverbs_method_def * const (*methods)[];
190 struct uverbs_object_tree_def {
192 const struct uverbs_object_def * const (*objects)[];
195 #define UA_FLAGS(_flags) .flags = _flags
196 #define __UVERBS_ATTR0(_id, _type, _fld, _attr, ...) \
197 ((const struct uverbs_attr_def) \
198 {.id = _id, .attr = {{._fld = {.type = _type, _attr, .flags = 0, } }, } })
199 #define __UVERBS_ATTR1(_id, _type, _fld, _attr, _extra1, ...) \
200 ((const struct uverbs_attr_def) \
201 {.id = _id, .attr = {{._fld = {.type = _type, _attr, _extra1 } },} })
202 #define __UVERBS_ATTR2(_id, _type, _fld, _attr, _extra1, _extra2) \
203 ((const struct uverbs_attr_def) \
204 {.id = _id, .attr = {{._fld = {.type = _type, _attr, _extra1, _extra2 } },} })
205 #define __UVERBS_ATTR(_id, _type, _fld, _attr, _extra1, _extra2, _n, ...) \
206 __UVERBS_ATTR##_n(_id, _type, _fld, _attr, _extra1, _extra2)
208 #define UVERBS_ATTR_TYPE(_type) \
209 .min_len = sizeof(_type), .len = sizeof(_type)
210 #define UVERBS_ATTR_STRUCT(_type, _last) \
211 .min_len = ((uintptr_t)(&((_type *)0)->_last + 1)), .len = sizeof(_type)
212 #define UVERBS_ATTR_SIZE(_min_len, _len) \
213 .min_len = _min_len, .len = _len
216 * In new compiler, UVERBS_ATTR could be simplified by declaring it as
217 * [_id] = {.type = _type, .len = _len, ##__VA_ARGS__}
218 * But since we support older compilers too, we need the more complex code.
220 #define UVERBS_ATTR(_id, _type, _fld, _attr, ...) \
221 __UVERBS_ATTR(_id, _type, _fld, _attr, ##__VA_ARGS__, 2, 1, 0)
222 #define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...) \
223 UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_IN, ptr, _len, ##__VA_ARGS__)
224 /* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */
225 #define UVERBS_ATTR_PTR_IN(_id, _type, ...) \
226 UVERBS_ATTR_PTR_IN_SZ(_id, _type, ##__VA_ARGS__)
227 #define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...) \
228 UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_OUT, ptr, _len, ##__VA_ARGS__)
229 #define UVERBS_ATTR_PTR_OUT(_id, _type, ...) \
230 UVERBS_ATTR_PTR_OUT_SZ(_id, _type, ##__VA_ARGS__)
231 #define UVERBS_ATTR_ENUM_IN(_id, _enum_arr, ...) \
232 UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_ENUM_IN, enum_def, \
233 .ids = (_enum_arr), \
234 .num_elems = ARRAY_SIZE(_enum_arr), ##__VA_ARGS__)
237 * In new compiler, UVERBS_ATTR_IDR (and FD) could be simplified by declaring
240 * .attr {.type = __obj_class, \
241 * .obj = {.obj_type = _idr_type, \
242 * .access = _access \
243 * }, ##__VA_ARGS__ } }
244 * But since we support older compilers too, we need the more complex code.
246 #define ___UVERBS_ATTR_OBJ0(_id, _obj_class, _obj_type, _access, ...)\
247 ((const struct uverbs_attr_def) \
249 .attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \
250 .access = _access, .flags = 0 } }, } })
251 #define ___UVERBS_ATTR_OBJ1(_id, _obj_class, _obj_type, _access, _flags)\
252 ((const struct uverbs_attr_def) \
254 .attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \
255 .access = _access, _flags} }, } })
256 #define ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, _flags, \
258 ___UVERBS_ATTR_OBJ##_n(_id, _obj_class, _obj_type, _access, _flags)
259 #define __UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, ...) \
260 ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, \
262 #define UVERBS_ATTR_IDR(_id, _idr_type, _access, ...) \
263 __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_IDR, _idr_type, _access,\
265 #define UVERBS_ATTR_FD(_id, _fd_type, _access, ...) \
266 __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_FD, _fd_type, \
267 (_access) + BUILD_BUG_ON_ZERO( \
268 (_access) != UVERBS_ACCESS_NEW && \
269 (_access) != UVERBS_ACCESS_READ), \
271 #define DECLARE_UVERBS_ATTR_SPEC(_name, ...) \
272 const struct uverbs_attr_def _name = __VA_ARGS__
274 #define DECLARE_UVERBS_ENUM(_name, ...) \
275 const struct uverbs_enum_spec _name = { \
276 .len = ARRAY_SIZE(((struct uverbs_attr_spec[]){__VA_ARGS__})),\
277 .ids = {__VA_ARGS__}, \
279 #define _UVERBS_METHOD_ATTRS_SZ(...) \
280 (sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\
281 sizeof(const struct uverbs_attr_def *))
282 #define _UVERBS_METHOD(_id, _handler, _flags, ...) \
283 ((const struct uverbs_method_def) { \
286 .handler = _handler, \
287 .num_attrs = _UVERBS_METHOD_ATTRS_SZ(__VA_ARGS__), \
288 .attrs = &(const struct uverbs_attr_def * const []){__VA_ARGS__} })
289 #define DECLARE_UVERBS_METHOD(_name, _id, _handler, ...) \
290 const struct uverbs_method_def _name = \
291 _UVERBS_METHOD(_id, _handler, 0, ##__VA_ARGS__)
292 #define DECLARE_UVERBS_CTX_METHOD(_name, _id, _handler, _flags, ...) \
293 const struct uverbs_method_def _name = \
294 _UVERBS_METHOD(_id, _handler, \
295 UVERBS_ACTION_FLAG_CREATE_ROOT, \
297 #define _UVERBS_OBJECT_METHODS_SZ(...) \
298 (sizeof((const struct uverbs_method_def * const []){__VA_ARGS__}) / \
299 sizeof(const struct uverbs_method_def *))
300 #define _UVERBS_OBJECT(_id, _type_attrs, ...) \
301 ((const struct uverbs_object_def) { \
303 .type_attrs = _type_attrs, \
304 .num_methods = _UVERBS_OBJECT_METHODS_SZ(__VA_ARGS__), \
305 .methods = &(const struct uverbs_method_def * const []){__VA_ARGS__} })
306 #define DECLARE_UVERBS_OBJECT(_name, _id, _type_attrs, ...) \
307 const struct uverbs_object_def _name = \
308 _UVERBS_OBJECT(_id, _type_attrs, ##__VA_ARGS__)
309 #define _UVERBS_TREE_OBJECTS_SZ(...) \
310 (sizeof((const struct uverbs_object_def * const []){__VA_ARGS__}) / \
311 sizeof(const struct uverbs_object_def *))
312 #define _UVERBS_OBJECT_TREE(...) \
313 ((const struct uverbs_object_tree_def) { \
314 .num_objects = _UVERBS_TREE_OBJECTS_SZ(__VA_ARGS__), \
315 .objects = &(const struct uverbs_object_def * const []){__VA_ARGS__} })
316 #define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \
317 const struct uverbs_object_tree_def _name = \
318 _UVERBS_OBJECT_TREE(__VA_ARGS__)
320 /* =================================================
321 * Parsing infrastructure
322 * =================================================
325 struct uverbs_ptr_attr {
328 /* Combination of bits from enum UVERBS_ATTR_F_XXXX */
333 struct uverbs_obj_attr {
334 /* pointer to the kernel descriptor -> type, access, etc */
335 const struct uverbs_obj_type *type;
336 struct ib_uobject *uobject;
337 /* fd or id in idr of this object */
343 * pointer to the user-space given attribute, in order to write the
344 * new uobject's id or update flags.
346 struct ib_uverbs_attr __user *uattr;
348 struct uverbs_ptr_attr ptr_attr;
349 struct uverbs_obj_attr obj_attr;
353 struct uverbs_attr_bundle_hash {
354 /* if bit i is set, it means attrs[i] contains valid information */
355 unsigned long *valid_bitmap;
358 * arrays of attributes, each element corresponds to the specification
359 * of the attribute in the same index.
361 struct uverbs_attr *attrs;
364 struct uverbs_attr_bundle {
366 struct uverbs_attr_bundle_hash hash[];
369 static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash,
372 return test_bit(idx, attrs_hash->valid_bitmap);
375 static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle,
378 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT;
380 if (attrs_bundle->num_buckets <= idx_bucket)
383 return uverbs_attr_is_valid_in_hash(&attrs_bundle->hash[idx_bucket],
384 idx & ~UVERBS_ID_NS_MASK);
387 #define IS_UVERBS_COPY_ERR(_ret) ((_ret) && (_ret) != -ENOENT)
389 static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle,
392 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT;
394 if (!uverbs_attr_is_valid(attrs_bundle, idx))
395 return ERR_PTR(-ENOENT);
397 return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK];
400 static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs_bundle,
403 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
406 return PTR_ERR(attr);
408 return attr->ptr_attr.enum_id;
411 static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_bundle,
414 struct ib_uobject *uobj =
415 uverbs_attr_get(attrs_bundle, idx)->obj_attr.uobject;
423 static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
424 size_t idx, const void *from, size_t size)
426 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
431 return PTR_ERR(attr);
433 min_size = min_t(size_t, attr->ptr_attr.len, size);
434 if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size))
437 flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT;
438 if (put_user(flags, &attr->uattr->flags))
444 static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr)
446 return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data);
449 static inline int _uverbs_copy_from(void *to,
450 const struct uverbs_attr_bundle *attrs_bundle,
454 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
457 return PTR_ERR(attr);
460 * Validation ensures attr->ptr_attr.len >= size. If the caller is
461 * using UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO then it must call
462 * uverbs_copy_from_or_zero.
464 if (unlikely(size < attr->ptr_attr.len))
467 if (uverbs_attr_ptr_is_inline(attr))
468 memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len);
469 else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data),
476 static inline int _uverbs_copy_from_or_zero(void *to,
477 const struct uverbs_attr_bundle *attrs_bundle,
481 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
485 return PTR_ERR(attr);
487 min_size = min_t(size_t, size, attr->ptr_attr.len);
489 if (uverbs_attr_ptr_is_inline(attr))
490 memcpy(to, &attr->ptr_attr.data, min_size);
491 else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data),
496 memset(to + min_size, 0, size - min_size);
501 #define uverbs_copy_from(to, attrs_bundle, idx) \
502 _uverbs_copy_from(to, attrs_bundle, idx, sizeof(*to))
504 #define uverbs_copy_from_or_zero(to, attrs_bundle, idx) \
505 _uverbs_copy_from_or_zero(to, attrs_bundle, idx, sizeof(*to))
507 /* =================================================
508 * Definitions -> Specs infrastructure
509 * =================================================
513 * uverbs_alloc_spec_tree - Merges different common and driver specific feature
514 * into one parsing tree that every uverbs command will be parsed upon.
516 * @num_trees: Number of trees in the array @trees.
517 * @trees: Array of pointers to tree root definitions to merge. Each such tree
518 * possibly contains objects, methods and attributes definitions.
521 * uverbs_root_spec *: The root of the merged parsing tree.
522 * On error, we return an error code. Error is checked via IS_ERR.
524 * The following merges could take place:
525 * a. Two trees representing the same method with different handler
526 * -> We take the handler of the tree that its handler != NULL
527 * and its index in the trees array is greater. The incentive for that
528 * is that developers are expected to first merge common trees and then
529 * merge trees that gives specialized the behaviour.
530 * b. Two trees representing the same object with different
531 * type_attrs (struct uverbs_obj_type):
532 * -> We take the type_attrs of the tree that its type_attr != NULL
533 * and its index in the trees array is greater. This could be used
534 * in order to override the free function, allocation size, etc.
535 * c. Two trees representing the same method attribute (same id but possibly
536 * different attributes):
537 * -> ERROR (-ENOENT), we believe that's not the programmer's intent.
539 * An object without any methods is considered invalid and will abort the
540 * function with -ENOENT error.
542 #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
543 struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
544 const struct uverbs_object_tree_def **trees);
545 void uverbs_free_spec_tree(struct uverbs_root_spec *root);
547 static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
548 const struct uverbs_object_tree_def **trees)
553 static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root)