blob: 4a4201d997a73c9c769b23b8c34d225c828ab786 [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 Barakd70724f2017-08-03 16:07:04 +030039#include <rdma/ib_user_ioctl_verbs.h>
Matan Barak1f7ff9d2018-03-19 15:02:33 +020040#include <rdma/ib_user_ioctl_cmds.h>
Matan Baraka0aa3092017-08-03 16:06:55 +030041
42/*
43 * =======================================
44 * Verbs action specifications
45 * =======================================
46 */
47
Matan Barakf43dbeb2017-08-03 16:06:56 +030048enum uverbs_attr_type {
49 UVERBS_ATTR_TYPE_NA,
Matan Barakfac96582017-08-03 16:06:57 +030050 UVERBS_ATTR_TYPE_PTR_IN,
51 UVERBS_ATTR_TYPE_PTR_OUT,
Matan Barakf43dbeb2017-08-03 16:06:56 +030052 UVERBS_ATTR_TYPE_IDR,
53 UVERBS_ATTR_TYPE_FD,
Matan Barak494c5582018-03-28 09:27:42 +030054 UVERBS_ATTR_TYPE_ENUM_IN,
Matan Barakf43dbeb2017-08-03 16:06:56 +030055};
56
Matan Baraka0aa3092017-08-03 16:06:55 +030057enum uverbs_obj_access {
58 UVERBS_ACCESS_READ,
59 UVERBS_ACCESS_WRITE,
60 UVERBS_ACCESS_NEW,
61 UVERBS_ACCESS_DESTROY
62};
63
Matan Barakfac96582017-08-03 16:06:57 +030064enum {
65 UVERBS_ATTR_SPEC_F_MANDATORY = 1U << 0,
Matan Barakc66db312018-03-19 15:02:36 +020066 /* Support extending attributes by length, validate all unknown size == zero */
67 UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO = 1U << 1,
Matan Barakfac96582017-08-03 16:06:57 +030068};
69
Matan Barak1f07e08f2018-03-19 15:02:35 +020070/* Specification of a single attribute inside the ioctl message */
Matan Barakf43dbeb2017-08-03 16:06:56 +030071struct uverbs_attr_spec {
Matan Barakfac96582017-08-03 16:06:57 +030072 union {
Matan Barak1f07e08f2018-03-19 15:02:35 +020073 /* Header shared by all following union members - to reduce space. */
Matan Barakfac96582017-08-03 16:06:57 +030074 struct {
Matan Barak1f07e08f2018-03-19 15:02:35 +020075 enum uverbs_attr_type type;
76 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
77 u8 flags;
78 };
79 struct {
80 enum uverbs_attr_type type;
81 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
82 u8 flags;
Matan Barakc66db312018-03-19 15:02:36 +020083 /* Current known size to kernel */
Matan Barak1f07e08f2018-03-19 15:02:35 +020084 u16 len;
Matan Barakc66db312018-03-19 15:02:36 +020085 /* User isn't allowed to provide something < min_len */
86 u16 min_len;
Matan Barak1f07e08f2018-03-19 15:02:35 +020087 } ptr;
88 struct {
89 enum uverbs_attr_type type;
90 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
91 u8 flags;
Matan Barakfac96582017-08-03 16:06:57 +030092 /*
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;
Matan Barak494c5582018-03-28 09:27:42 +030099 struct {
100 enum uverbs_attr_type type;
101 /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
102 u8 flags;
103 u8 num_elems;
104 /*
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.
108 */
109 const struct uverbs_attr_spec *ids;
110 } enum_def;
Matan Barakfac96582017-08-03 16:06:57 +0300111 };
Matan Barakf43dbeb2017-08-03 16:06:56 +0300112};
113
114struct uverbs_attr_spec_hash {
115 size_t num_attrs;
Matan Barakfac96582017-08-03 16:06:57 +0300116 unsigned long *mandatory_attrs_bitmask;
Matan Barakf43dbeb2017-08-03 16:06:56 +0300117 struct uverbs_attr_spec attrs[0];
118};
119
Matan Barakfac96582017-08-03 16:06:57 +0300120struct uverbs_attr_bundle;
121struct ib_uverbs_file;
122
123enum {
124 /*
125 * Action marked with this flag creates a context (or root for all
126 * objects).
127 */
128 UVERBS_ACTION_FLAG_CREATE_ROOT = 1U << 0,
129};
130
131struct uverbs_method_spec {
132 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
133 u32 flags;
134 size_t num_buckets;
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];
139};
140
141struct uverbs_method_spec_hash {
142 size_t num_methods;
143 struct uverbs_method_spec *methods[0];
144};
145
146struct uverbs_object_spec {
147 const struct uverbs_obj_type *type_attrs;
148 size_t num_buckets;
149 struct uverbs_method_spec_hash *method_buckets[0];
150};
151
152struct uverbs_object_spec_hash {
153 size_t num_objects;
154 struct uverbs_object_spec *objects[0];
155};
156
157struct uverbs_root_spec {
158 size_t num_buckets;
159 struct uverbs_object_spec_hash *object_buckets[0];
160};
161
Matan Barak50090102017-08-03 16:06:58 +0300162/*
163 * =======================================
164 * Verbs definitions
165 * =======================================
166 */
167
Matan Barak09e3ebf2017-08-03 16:06:59 +0300168struct uverbs_attr_def {
169 u16 id;
170 struct uverbs_attr_spec attr;
171};
172
173struct uverbs_method_def {
174 u16 id;
175 /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
176 u32 flags;
177 size_t num_attrs;
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);
181};
182
Matan Barak50090102017-08-03 16:06:58 +0300183struct uverbs_object_def {
Matan Barak09e3ebf2017-08-03 16:06:59 +0300184 u16 id;
Matan Barak50090102017-08-03 16:06:58 +0300185 const struct uverbs_obj_type *type_attrs;
Matan Barak09e3ebf2017-08-03 16:06:59 +0300186 size_t num_methods;
187 const struct uverbs_method_def * const (*methods)[];
188};
189
190struct uverbs_object_tree_def {
191 size_t num_objects;
192 const struct uverbs_object_def * const (*objects)[];
Matan Barak50090102017-08-03 16:06:58 +0300193};
194
Matan Barak35410302017-08-03 16:07:01 +0300195#define UA_FLAGS(_flags) .flags = _flags
Matan Barakc66db312018-03-19 15:02:36 +0200196#define __UVERBS_ATTR0(_id, _type, _fld, _attr, ...) \
Matan Barak35410302017-08-03 16:07:01 +0300197 ((const struct uverbs_attr_def) \
Matan Barakc66db312018-03-19 15:02:36 +0200198 {.id = _id, .attr = {{._fld = {.type = _type, _attr, .flags = 0, } }, } })
199#define __UVERBS_ATTR1(_id, _type, _fld, _attr, _extra1, ...) \
Matan Barak35410302017-08-03 16:07:01 +0300200 ((const struct uverbs_attr_def) \
Matan Barakc66db312018-03-19 15:02:36 +0200201 {.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)
207
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
214
Matan Barak35410302017-08-03 16:07:01 +0300215/*
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.
219 */
Matan Barakc66db312018-03-19 15:02:36 +0200220#define UVERBS_ATTR(_id, _type, _fld, _attr, ...) \
221 __UVERBS_ATTR(_id, _type, _fld, _attr, ##__VA_ARGS__, 2, 1, 0)
Matan Barak35410302017-08-03 16:07:01 +0300222#define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...) \
Matan Barakc66db312018-03-19 15:02:36 +0200223 UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_IN, ptr, _len, ##__VA_ARGS__)
Matan Barak35410302017-08-03 16:07:01 +0300224/* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */
225#define UVERBS_ATTR_PTR_IN(_id, _type, ...) \
Matan Barakc66db312018-03-19 15:02:36 +0200226 UVERBS_ATTR_PTR_IN_SZ(_id, _type, ##__VA_ARGS__)
Matan Barak35410302017-08-03 16:07:01 +0300227#define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...) \
Matan Barakc66db312018-03-19 15:02:36 +0200228 UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_OUT, ptr, _len, ##__VA_ARGS__)
Matan Barak35410302017-08-03 16:07:01 +0300229#define UVERBS_ATTR_PTR_OUT(_id, _type, ...) \
Matan Barakc66db312018-03-19 15:02:36 +0200230 UVERBS_ATTR_PTR_OUT_SZ(_id, _type, ##__VA_ARGS__)
Matan Barak494c5582018-03-28 09:27:42 +0300231#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__)
Matan Barak35410302017-08-03 16:07:01 +0300235
236/*
237 * In new compiler, UVERBS_ATTR_IDR (and FD) could be simplified by declaring
238 * it as
239 * {.id = _id, \
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.
245 */
246#define ___UVERBS_ATTR_OBJ0(_id, _obj_class, _obj_type, _access, ...)\
247 ((const struct uverbs_attr_def) \
248 {.id = _id, \
Matan Barak1f07e08f2018-03-19 15:02:35 +0200249 .attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \
250 .access = _access, .flags = 0 } }, } })
Matan Barak35410302017-08-03 16:07:01 +0300251#define ___UVERBS_ATTR_OBJ1(_id, _obj_class, _obj_type, _access, _flags)\
252 ((const struct uverbs_attr_def) \
253 {.id = _id, \
Matan Barak1f07e08f2018-03-19 15:02:35 +0200254 .attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \
255 .access = _access, _flags} }, } })
Matan Barak35410302017-08-03 16:07:01 +0300256#define ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, _flags, \
257 _n, ...) \
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, \
261 ##__VA_ARGS__, 1, 0)
262#define UVERBS_ATTR_IDR(_id, _idr_type, _access, ...) \
263 __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_IDR, _idr_type, _access,\
264 ##__VA_ARGS__)
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), \
270 ##__VA_ARGS__)
271#define DECLARE_UVERBS_ATTR_SPEC(_name, ...) \
272 const struct uverbs_attr_def _name = __VA_ARGS__
273
Matan Barak494c5582018-03-28 09:27:42 +0300274#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__}, \
278 }
Matan Barak35410302017-08-03 16:07:01 +0300279#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) { \
284 .id = _id, \
285 .flags = _flags, \
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, \
296 ##__VA_ARGS__)
297#define _UVERBS_OBJECT_METHODS_SZ(...) \
298 (sizeof((const struct uverbs_method_def * const []){__VA_ARGS__}) / \
299 sizeof(const struct uverbs_method_def *))
Matan Barak50090102017-08-03 16:06:58 +0300300#define _UVERBS_OBJECT(_id, _type_attrs, ...) \
301 ((const struct uverbs_object_def) { \
Matan Barak09e3ebf2017-08-03 16:06:59 +0300302 .id = _id, \
Matan Barak35410302017-08-03 16:07:01 +0300303 .type_attrs = _type_attrs, \
304 .num_methods = _UVERBS_OBJECT_METHODS_SZ(__VA_ARGS__), \
305 .methods = &(const struct uverbs_method_def * const []){__VA_ARGS__} })
Matan Barak50090102017-08-03 16:06:58 +0300306#define DECLARE_UVERBS_OBJECT(_name, _id, _type_attrs, ...) \
307 const struct uverbs_object_def _name = \
308 _UVERBS_OBJECT(_id, _type_attrs, ##__VA_ARGS__)
Matan Barak09e3ebf2017-08-03 16:06:59 +0300309#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__)
319
Matan Barakfac96582017-08-03 16:06:57 +0300320/* =================================================
321 * Parsing infrastructure
322 * =================================================
323 */
324
325struct uverbs_ptr_attr {
Jason Gunthorpe2f360282018-02-13 12:18:31 +0200326 u64 data;
Matan Barakfac96582017-08-03 16:06:57 +0300327 u16 len;
328 /* Combination of bits from enum UVERBS_ATTR_F_XXXX */
329 u16 flags;
Matan Barak494c5582018-03-28 09:27:42 +0300330 u8 enum_id;
Matan Barakfac96582017-08-03 16:06:57 +0300331};
332
Matan Barakf43dbeb2017-08-03 16:06:56 +0300333struct uverbs_obj_attr {
Matan Barakfac96582017-08-03 16:06:57 +0300334 /* pointer to the kernel descriptor -> type, access, etc */
335 const struct uverbs_obj_type *type;
Matan Barakf43dbeb2017-08-03 16:06:56 +0300336 struct ib_uobject *uobject;
Matan Barakfac96582017-08-03 16:06:57 +0300337 /* fd or id in idr of this object */
338 int id;
Matan Barakf43dbeb2017-08-03 16:06:56 +0300339};
340
341struct uverbs_attr {
Matan Barakfac96582017-08-03 16:06:57 +0300342 /*
343 * pointer to the user-space given attribute, in order to write the
344 * new uobject's id or update flags.
345 */
346 struct ib_uverbs_attr __user *uattr;
347 union {
348 struct uverbs_ptr_attr ptr_attr;
349 struct uverbs_obj_attr obj_attr;
350 };
Matan Barakf43dbeb2017-08-03 16:06:56 +0300351};
352
353struct uverbs_attr_bundle_hash {
354 /* if bit i is set, it means attrs[i] contains valid information */
355 unsigned long *valid_bitmap;
356 size_t num_attrs;
357 /*
358 * arrays of attributes, each element corresponds to the specification
359 * of the attribute in the same index.
360 */
361 struct uverbs_attr *attrs;
362};
363
364struct uverbs_attr_bundle {
365 size_t num_buckets;
366 struct uverbs_attr_bundle_hash hash[];
367};
368
369static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash,
370 unsigned int idx)
371{
372 return test_bit(idx, attrs_hash->valid_bitmap);
373}
374
Matan Barak35410302017-08-03 16:07:01 +0300375static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle,
376 unsigned int idx)
377{
378 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT;
379
380 if (attrs_bundle->num_buckets <= idx_bucket)
381 return false;
382
383 return uverbs_attr_is_valid_in_hash(&attrs_bundle->hash[idx_bucket],
384 idx & ~UVERBS_ID_NS_MASK);
385}
386
Matan Barak41b2a712018-03-19 15:02:38 +0200387#define IS_UVERBS_COPY_ERR(_ret) ((_ret) && (_ret) != -ENOENT)
388
Matan Barakd70724f2017-08-03 16:07:04 +0300389static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle,
390 u16 idx)
391{
392 u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT;
393
394 if (!uverbs_attr_is_valid(attrs_bundle, idx))
395 return ERR_PTR(-ENOENT);
396
397 return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK];
398}
399
Matan Barak494c5582018-03-28 09:27:42 +0300400static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs_bundle,
401 u16 idx)
402{
403 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
404
405 if (IS_ERR(attr))
406 return PTR_ERR(attr);
407
408 return attr->ptr_attr.enum_id;
409}
410
Ariel Levkovichbe934cc2018-04-05 18:53:25 +0300411static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_bundle,
412 u16 idx)
413{
414 struct ib_uobject *uobj =
415 uverbs_attr_get(attrs_bundle, idx)->obj_attr.uobject;
416
417 if (IS_ERR(uobj))
418 return uobj;
419
420 return uobj->object;
421}
422
Matan Barakd70724f2017-08-03 16:07:04 +0300423static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
Matan Barak89d9e8d2018-02-13 12:18:29 +0200424 size_t idx, const void *from, size_t size)
Matan Barakd70724f2017-08-03 16:07:04 +0300425{
426 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
427 u16 flags;
Matan Barak89d9e8d2018-02-13 12:18:29 +0200428 size_t min_size;
Matan Barakd70724f2017-08-03 16:07:04 +0300429
430 if (IS_ERR(attr))
431 return PTR_ERR(attr);
432
Matan Barak89d9e8d2018-02-13 12:18:29 +0200433 min_size = min_t(size_t, attr->ptr_attr.len, size);
Jason Gunthorpe2f360282018-02-13 12:18:31 +0200434 if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size))
Matan Barak89d9e8d2018-02-13 12:18:29 +0200435 return -EFAULT;
436
Matan Barakd70724f2017-08-03 16:07:04 +0300437 flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT;
Matan Barak89d9e8d2018-02-13 12:18:29 +0200438 if (put_user(flags, &attr->uattr->flags))
439 return -EFAULT;
440
441 return 0;
Matan Barakd70724f2017-08-03 16:07:04 +0300442}
443
Matan Barak89d9e8d2018-02-13 12:18:29 +0200444static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr)
445{
446 return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data);
447}
448
449static inline int _uverbs_copy_from(void *to,
Matan Barakd70724f2017-08-03 16:07:04 +0300450 const struct uverbs_attr_bundle *attrs_bundle,
Matan Barak89d9e8d2018-02-13 12:18:29 +0200451 size_t idx,
452 size_t size)
Matan Barakd70724f2017-08-03 16:07:04 +0300453{
454 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
455
456 if (IS_ERR(attr))
457 return PTR_ERR(attr);
458
Matan Barak89d9e8d2018-02-13 12:18:29 +0200459 /*
460 * Validation ensures attr->ptr_attr.len >= size. If the caller is
Matan Barakc66db312018-03-19 15:02:36 +0200461 * using UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO then it must call
462 * uverbs_copy_from_or_zero.
Matan Barak89d9e8d2018-02-13 12:18:29 +0200463 */
464 if (unlikely(size < attr->ptr_attr.len))
465 return -EINVAL;
466
467 if (uverbs_attr_ptr_is_inline(attr))
Matan Barakd70724f2017-08-03 16:07:04 +0300468 memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len);
Jason Gunthorpe2f360282018-02-13 12:18:31 +0200469 else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data),
470 attr->ptr_attr.len))
Matan Barakd70724f2017-08-03 16:07:04 +0300471 return -EFAULT;
472
473 return 0;
474}
475
Matan Barakc66db312018-03-19 15:02:36 +0200476static inline int _uverbs_copy_from_or_zero(void *to,
477 const struct uverbs_attr_bundle *attrs_bundle,
478 size_t idx,
479 size_t size)
480{
481 const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
482 size_t min_size;
483
484 if (IS_ERR(attr))
485 return PTR_ERR(attr);
486
487 min_size = min_t(size_t, size, attr->ptr_attr.len);
488
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),
492 min_size))
493 return -EFAULT;
494
495 if (size > min_size)
496 memset(to + min_size, 0, size - min_size);
497
498 return 0;
499}
500
Matan Barakd70724f2017-08-03 16:07:04 +0300501#define uverbs_copy_from(to, attrs_bundle, idx) \
Matan Barak89d9e8d2018-02-13 12:18:29 +0200502 _uverbs_copy_from(to, attrs_bundle, idx, sizeof(*to))
Matan Barakd70724f2017-08-03 16:07:04 +0300503
Matan Barakc66db312018-03-19 15:02:36 +0200504#define uverbs_copy_from_or_zero(to, attrs_bundle, idx) \
505 _uverbs_copy_from_or_zero(to, attrs_bundle, idx, sizeof(*to))
506
Matan Barak118620d2017-08-03 16:07:00 +0300507/* =================================================
508 * Definitions -> Specs infrastructure
509 * =================================================
510 */
Matan Baraka0aa3092017-08-03 16:06:55 +0300511
Matan Barak118620d2017-08-03 16:07:00 +0300512/*
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.
515 *
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.
519 *
520 * Returns:
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.
523 *
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.
538 *
539 * An object without any methods is considered invalid and will abort the
540 * function with -ENOENT error.
541 */
Matan Barak52427112017-08-03 16:07:06 +0300542#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
Matan Barak118620d2017-08-03 16:07:00 +0300543struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
544 const struct uverbs_object_tree_def **trees);
545void uverbs_free_spec_tree(struct uverbs_root_spec *root);
Matan Barak52427112017-08-03 16:07:06 +0300546#else
547static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
548 const struct uverbs_object_tree_def **trees)
549{
550 return NULL;
551}
552
553static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root)
554{
555}
556#endif
Matan Barak118620d2017-08-03 16:07:00 +0300557
558#endif