blob: 9a8d217cdc1db37bc6e126d3d3311b0225c0ae5a [file] [log] [blame]
Matan Baraka0aa3092017-08-03 16:06:55 +03001/*
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>
Matan Barak35410302017-08-03 16:07:01 +030037#include <linux/uaccess.h>
38#include <rdma/rdma_user_ioctl.h>
Matan Baraka0aa3092017-08-03 16:06:55 +030039
40/*
41 * =======================================
42 * Verbs action specifications
43 * =======================================
44 */
45
Matan Barakf43dbeb2017-08-03 16:06:56 +030046enum uverbs_attr_type {
47 UVERBS_ATTR_TYPE_NA,
Matan Barakfac96582017-08-03 16:06:57 +030048 UVERBS_ATTR_TYPE_PTR_IN,
49 UVERBS_ATTR_TYPE_PTR_OUT,
Matan Barakf43dbeb2017-08-03 16:06:56 +030050 UVERBS_ATTR_TYPE_IDR,
51 UVERBS_ATTR_TYPE_FD,
52};
53
Matan Baraka0aa3092017-08-03 16:06:55 +030054enum uverbs_obj_access {
55 UVERBS_ACCESS_READ,
56 UVERBS_ACCESS_WRITE,
57 UVERBS_ACCESS_NEW,
58 UVERBS_ACCESS_DESTROY
59};
60
Matan Barakfac96582017-08-03 16:06:57 +030061enum {
62 UVERBS_ATTR_SPEC_F_MANDATORY = 1U << 0,
63 /* Support extending attributes by length */
64 UVERBS_ATTR_SPEC_F_MIN_SZ = 1U << 1,
65};
66
Matan Barakf43dbeb2017-08-03 16:06:56 +030067struct uverbs_attr_spec {
68 enum uverbs_attr_type type;
Matan Barakfac96582017-08-03 16:06:57 +030069 union {
70 u16 len;
71 struct {
72 /*
73 * higher bits mean the namespace and lower bits mean
74 * the type id within the namespace.
75 */
76 u16 obj_type;
77 u8 access;
78 } obj;
79 };
80 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
81 u8 flags;
Matan Barakf43dbeb2017-08-03 16:06:56 +030082};
83
84struct uverbs_attr_spec_hash {
85 size_t num_attrs;
Matan Barakfac96582017-08-03 16:06:57 +030086 unsigned long *mandatory_attrs_bitmask;
Matan Barakf43dbeb2017-08-03 16:06:56 +030087 struct uverbs_attr_spec attrs[0];
88};
89
Matan Barakfac96582017-08-03 16:06:57 +030090struct uverbs_attr_bundle;
91struct ib_uverbs_file;
92
93enum {
94 /*
95 * Action marked with this flag creates a context (or root for all
96 * objects).
97 */
98 UVERBS_ACTION_FLAG_CREATE_ROOT = 1U << 0,
99};
100
101struct uverbs_method_spec {
102 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
103 u32 flags;
104 size_t num_buckets;
105 size_t num_child_attrs;
106 int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile,
107 struct uverbs_attr_bundle *ctx);
108 struct uverbs_attr_spec_hash *attr_buckets[0];
109};
110
111struct uverbs_method_spec_hash {
112 size_t num_methods;
113 struct uverbs_method_spec *methods[0];
114};
115
116struct uverbs_object_spec {
117 const struct uverbs_obj_type *type_attrs;
118 size_t num_buckets;
119 struct uverbs_method_spec_hash *method_buckets[0];
120};
121
122struct uverbs_object_spec_hash {
123 size_t num_objects;
124 struct uverbs_object_spec *objects[0];
125};
126
127struct uverbs_root_spec {
128 size_t num_buckets;
129 struct uverbs_object_spec_hash *object_buckets[0];
130};
131
Matan Barak50090102017-08-03 16:06:58 +0300132/*
133 * =======================================
134 * Verbs definitions
135 * =======================================
136 */
137
Matan Barak09e3ebf2017-08-03 16:06:59 +0300138struct uverbs_attr_def {
139 u16 id;
140 struct uverbs_attr_spec attr;
141};
142
143struct uverbs_method_def {
144 u16 id;
145 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
146 u32 flags;
147 size_t num_attrs;
148 const struct uverbs_attr_def * const (*attrs)[];
149 int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile,
150 struct uverbs_attr_bundle *ctx);
151};
152
Matan Barak50090102017-08-03 16:06:58 +0300153struct uverbs_object_def {
Matan Barak09e3ebf2017-08-03 16:06:59 +0300154 u16 id;
Matan Barak50090102017-08-03 16:06:58 +0300155 const struct uverbs_obj_type *type_attrs;
Matan Barak09e3ebf2017-08-03 16:06:59 +0300156 size_t num_methods;
157 const struct uverbs_method_def * const (*methods)[];
158};
159
160struct uverbs_object_tree_def {
161 size_t num_objects;
162 const struct uverbs_object_def * const (*objects)[];
Matan Barak50090102017-08-03 16:06:58 +0300163};
164
Matan Barak35410302017-08-03 16:07:01 +0300165#define UA_FLAGS(_flags) .flags = _flags
166#define __UVERBS_ATTR0(_id, _len, _type, ...) \
167 ((const struct uverbs_attr_def) \
168 {.id = _id, .attr = {.type = _type, {.len = _len}, .flags = 0, } })
169#define __UVERBS_ATTR1(_id, _len, _type, _flags) \
170 ((const struct uverbs_attr_def) \
171 {.id = _id, .attr = {.type = _type, {.len = _len}, _flags, } })
172#define __UVERBS_ATTR(_id, _len, _type, _flags, _n, ...) \
173 __UVERBS_ATTR##_n(_id, _len, _type, _flags)
174/*
175 * In new compiler, UVERBS_ATTR could be simplified by declaring it as
176 * [_id] = {.type = _type, .len = _len, ##__VA_ARGS__}
177 * But since we support older compilers too, we need the more complex code.
178 */
179#define UVERBS_ATTR(_id, _len, _type, ...) \
180 __UVERBS_ATTR(_id, _len, _type, ##__VA_ARGS__, 1, 0)
181#define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...) \
182 UVERBS_ATTR(_id, _len, UVERBS_ATTR_TYPE_PTR_IN, ##__VA_ARGS__)
183/* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */
184#define UVERBS_ATTR_PTR_IN(_id, _type, ...) \
185 UVERBS_ATTR_PTR_IN_SZ(_id, sizeof(_type), ##__VA_ARGS__)
186#define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...) \
187 UVERBS_ATTR(_id, _len, UVERBS_ATTR_TYPE_PTR_OUT, ##__VA_ARGS__)
188#define UVERBS_ATTR_PTR_OUT(_id, _type, ...) \
189 UVERBS_ATTR_PTR_OUT_SZ(_id, sizeof(_type), ##__VA_ARGS__)
190
191/*
192 * In new compiler, UVERBS_ATTR_IDR (and FD) could be simplified by declaring
193 * it as
194 * {.id = _id, \
195 * .attr {.type = __obj_class, \
196 * .obj = {.obj_type = _idr_type, \
197 * .access = _access \
198 * }, ##__VA_ARGS__ } }
199 * But since we support older compilers too, we need the more complex code.
200 */
201#define ___UVERBS_ATTR_OBJ0(_id, _obj_class, _obj_type, _access, ...)\
202 ((const struct uverbs_attr_def) \
203 {.id = _id, \
204 .attr = {.type = _obj_class, \
205 {.obj = {.obj_type = _obj_type, .access = _access } },\
206 .flags = 0} })
207#define ___UVERBS_ATTR_OBJ1(_id, _obj_class, _obj_type, _access, _flags)\
208 ((const struct uverbs_attr_def) \
209 {.id = _id, \
210 .attr = {.type = _obj_class, \
211 {.obj = {.obj_type = _obj_type, .access = _access} }, \
212 _flags} })
213#define ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, _flags, \
214 _n, ...) \
215 ___UVERBS_ATTR_OBJ##_n(_id, _obj_class, _obj_type, _access, _flags)
216#define __UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, ...) \
217 ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, \
218 ##__VA_ARGS__, 1, 0)
219#define UVERBS_ATTR_IDR(_id, _idr_type, _access, ...) \
220 __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_IDR, _idr_type, _access,\
221 ##__VA_ARGS__)
222#define UVERBS_ATTR_FD(_id, _fd_type, _access, ...) \
223 __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_FD, _fd_type, \
224 (_access) + BUILD_BUG_ON_ZERO( \
225 (_access) != UVERBS_ACCESS_NEW && \
226 (_access) != UVERBS_ACCESS_READ), \
227 ##__VA_ARGS__)
228#define DECLARE_UVERBS_ATTR_SPEC(_name, ...) \
229 const struct uverbs_attr_def _name = __VA_ARGS__
230
231#define _UVERBS_METHOD_ATTRS_SZ(...) \
232 (sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\
233 sizeof(const struct uverbs_attr_def *))
234#define _UVERBS_METHOD(_id, _handler, _flags, ...) \
235 ((const struct uverbs_method_def) { \
236 .id = _id, \
237 .flags = _flags, \
238 .handler = _handler, \
239 .num_attrs = _UVERBS_METHOD_ATTRS_SZ(__VA_ARGS__), \
240 .attrs = &(const struct uverbs_attr_def * const []){__VA_ARGS__} })
241#define DECLARE_UVERBS_METHOD(_name, _id, _handler, ...) \
242 const struct uverbs_method_def _name = \
243 _UVERBS_METHOD(_id, _handler, 0, ##__VA_ARGS__)
244#define DECLARE_UVERBS_CTX_METHOD(_name, _id, _handler, _flags, ...) \
245 const struct uverbs_method_def _name = \
246 _UVERBS_METHOD(_id, _handler, \
247 UVERBS_ACTION_FLAG_CREATE_ROOT, \
248 ##__VA_ARGS__)
249#define _UVERBS_OBJECT_METHODS_SZ(...) \
250 (sizeof((const struct uverbs_method_def * const []){__VA_ARGS__}) / \
251 sizeof(const struct uverbs_method_def *))
Matan Barak50090102017-08-03 16:06:58 +0300252#define _UVERBS_OBJECT(_id, _type_attrs, ...) \
253 ((const struct uverbs_object_def) { \
Matan Barak09e3ebf2017-08-03 16:06:59 +0300254 .id = _id, \
Matan Barak35410302017-08-03 16:07:01 +0300255 .type_attrs = _type_attrs, \
256 .num_methods = _UVERBS_OBJECT_METHODS_SZ(__VA_ARGS__), \
257 .methods = &(const struct uverbs_method_def * const []){__VA_ARGS__} })
Matan Barak50090102017-08-03 16:06:58 +0300258#define DECLARE_UVERBS_OBJECT(_name, _id, _type_attrs, ...) \
259 const struct uverbs_object_def _name = \
260 _UVERBS_OBJECT(_id, _type_attrs, ##__VA_ARGS__)
Matan Barak09e3ebf2017-08-03 16:06:59 +0300261#define _UVERBS_TREE_OBJECTS_SZ(...) \
262 (sizeof((const struct uverbs_object_def * const []){__VA_ARGS__}) / \
263 sizeof(const struct uverbs_object_def *))
264#define _UVERBS_OBJECT_TREE(...) \
265 ((const struct uverbs_object_tree_def) { \
266 .num_objects = _UVERBS_TREE_OBJECTS_SZ(__VA_ARGS__), \
267 .objects = &(const struct uverbs_object_def * const []){__VA_ARGS__} })
268#define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \
269 const struct uverbs_object_tree_def _name = \
270 _UVERBS_OBJECT_TREE(__VA_ARGS__)
271
Matan Barakfac96582017-08-03 16:06:57 +0300272/* =================================================
273 * Parsing infrastructure
274 * =================================================
275 */
276
277struct uverbs_ptr_attr {
278 union {
279 u64 data;
280 void __user *ptr;
281 };
282 u16 len;
283 /* Combination of bits from enum UVERBS_ATTR_F_XXXX */
284 u16 flags;
285};
286
Matan Barakf43dbeb2017-08-03 16:06:56 +0300287struct uverbs_obj_attr {
Matan Barakfac96582017-08-03 16:06:57 +0300288 /* pointer to the kernel descriptor -> type, access, etc */
289 const struct uverbs_obj_type *type;
Matan Barakf43dbeb2017-08-03 16:06:56 +0300290 struct ib_uobject *uobject;
Matan Barakfac96582017-08-03 16:06:57 +0300291 /* fd or id in idr of this object */
292 int id;
Matan Barakf43dbeb2017-08-03 16:06:56 +0300293};
294
295struct uverbs_attr {
Matan Barakfac96582017-08-03 16:06:57 +0300296 /*
297 * pointer to the user-space given attribute, in order to write the
298 * new uobject's id or update flags.
299 */
300 struct ib_uverbs_attr __user *uattr;
301 union {
302 struct uverbs_ptr_attr ptr_attr;
303 struct uverbs_obj_attr obj_attr;
304 };
Matan Barakf43dbeb2017-08-03 16:06:56 +0300305};
306
307struct uverbs_attr_bundle_hash {
308 /* if bit i is set, it means attrs[i] contains valid information */
309 unsigned long *valid_bitmap;
310 size_t num_attrs;
311 /*
312 * arrays of attributes, each element corresponds to the specification
313 * of the attribute in the same index.
314 */
315 struct uverbs_attr *attrs;
316};
317
318struct uverbs_attr_bundle {
319 size_t num_buckets;
320 struct uverbs_attr_bundle_hash hash[];
321};
322
323static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash,
324 unsigned int idx)
325{
326 return test_bit(idx, attrs_hash->valid_bitmap);
327}
328
Matan Barak35410302017-08-03 16:07:01 +0300329static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle,
330 unsigned int idx)
331{
332 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT;
333
334 if (attrs_bundle->num_buckets <= idx_bucket)
335 return false;
336
337 return uverbs_attr_is_valid_in_hash(&attrs_bundle->hash[idx_bucket],
338 idx & ~UVERBS_ID_NS_MASK);
339}
340
Matan Barak118620d2017-08-03 16:07:00 +0300341/* =================================================
342 * Definitions -> Specs infrastructure
343 * =================================================
344 */
Matan Baraka0aa3092017-08-03 16:06:55 +0300345
Matan Barak118620d2017-08-03 16:07:00 +0300346/*
347 * uverbs_alloc_spec_tree - Merges different common and driver specific feature
348 * into one parsing tree that every uverbs command will be parsed upon.
349 *
350 * @num_trees: Number of trees in the array @trees.
351 * @trees: Array of pointers to tree root definitions to merge. Each such tree
352 * possibly contains objects, methods and attributes definitions.
353 *
354 * Returns:
355 * uverbs_root_spec *: The root of the merged parsing tree.
356 * On error, we return an error code. Error is checked via IS_ERR.
357 *
358 * The following merges could take place:
359 * a. Two trees representing the same method with different handler
360 * -> We take the handler of the tree that its handler != NULL
361 * and its index in the trees array is greater. The incentive for that
362 * is that developers are expected to first merge common trees and then
363 * merge trees that gives specialized the behaviour.
364 * b. Two trees representing the same object with different
365 * type_attrs (struct uverbs_obj_type):
366 * -> We take the type_attrs of the tree that its type_attr != NULL
367 * and its index in the trees array is greater. This could be used
368 * in order to override the free function, allocation size, etc.
369 * c. Two trees representing the same method attribute (same id but possibly
370 * different attributes):
371 * -> ERROR (-ENOENT), we believe that's not the programmer's intent.
372 *
373 * An object without any methods is considered invalid and will abort the
374 * function with -ENOENT error.
375 */
376struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
377 const struct uverbs_object_tree_def **trees);
378void uverbs_free_spec_tree(struct uverbs_root_spec *root);
379
380#endif