1a0aa309cSMatan Barak /* 2a0aa309cSMatan Barak * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved. 3a0aa309cSMatan Barak * 4a0aa309cSMatan Barak * This software is available to you under a choice of one of two 5a0aa309cSMatan Barak * licenses. You may choose to be licensed under the terms of the GNU 6a0aa309cSMatan Barak * General Public License (GPL) Version 2, available from the file 7a0aa309cSMatan Barak * COPYING in the main directory of this source tree, or the 8a0aa309cSMatan Barak * OpenIB.org BSD license below: 9a0aa309cSMatan Barak * 10a0aa309cSMatan Barak * Redistribution and use in source and binary forms, with or 11a0aa309cSMatan Barak * without modification, are permitted provided that the following 12a0aa309cSMatan Barak * conditions are met: 13a0aa309cSMatan Barak * 14a0aa309cSMatan Barak * - Redistributions of source code must retain the above 15a0aa309cSMatan Barak * copyright notice, this list of conditions and the following 16a0aa309cSMatan Barak * disclaimer. 17a0aa309cSMatan Barak * 18a0aa309cSMatan Barak * - Redistributions in binary form must reproduce the above 19a0aa309cSMatan Barak * copyright notice, this list of conditions and the following 20a0aa309cSMatan Barak * disclaimer in the documentation and/or other materials 21a0aa309cSMatan Barak * provided with the distribution. 22a0aa309cSMatan Barak * 23a0aa309cSMatan Barak * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24a0aa309cSMatan Barak * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25a0aa309cSMatan Barak * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26a0aa309cSMatan Barak * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27a0aa309cSMatan Barak * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28a0aa309cSMatan Barak * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29a0aa309cSMatan Barak * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30a0aa309cSMatan Barak * SOFTWARE. 31a0aa309cSMatan Barak */ 32a0aa309cSMatan Barak 33a0aa309cSMatan Barak #ifndef _UVERBS_IOCTL_ 34a0aa309cSMatan Barak #define _UVERBS_IOCTL_ 35a0aa309cSMatan Barak 36a0aa309cSMatan Barak #include <rdma/uverbs_types.h> 37a0aa309cSMatan Barak 38a0aa309cSMatan Barak /* 39a0aa309cSMatan Barak * ======================================= 40a0aa309cSMatan Barak * Verbs action specifications 41a0aa309cSMatan Barak * ======================================= 42a0aa309cSMatan Barak */ 43a0aa309cSMatan Barak 44f43dbebfSMatan Barak enum uverbs_attr_type { 45f43dbebfSMatan Barak UVERBS_ATTR_TYPE_NA, 46fac9658cSMatan Barak UVERBS_ATTR_TYPE_PTR_IN, 47fac9658cSMatan Barak UVERBS_ATTR_TYPE_PTR_OUT, 48f43dbebfSMatan Barak UVERBS_ATTR_TYPE_IDR, 49f43dbebfSMatan Barak UVERBS_ATTR_TYPE_FD, 50f43dbebfSMatan Barak }; 51f43dbebfSMatan Barak 52a0aa309cSMatan Barak enum uverbs_obj_access { 53a0aa309cSMatan Barak UVERBS_ACCESS_READ, 54a0aa309cSMatan Barak UVERBS_ACCESS_WRITE, 55a0aa309cSMatan Barak UVERBS_ACCESS_NEW, 56a0aa309cSMatan Barak UVERBS_ACCESS_DESTROY 57a0aa309cSMatan Barak }; 58a0aa309cSMatan Barak 59fac9658cSMatan Barak enum { 60fac9658cSMatan Barak UVERBS_ATTR_SPEC_F_MANDATORY = 1U << 0, 61fac9658cSMatan Barak /* Support extending attributes by length */ 62fac9658cSMatan Barak UVERBS_ATTR_SPEC_F_MIN_SZ = 1U << 1, 63fac9658cSMatan Barak }; 64fac9658cSMatan Barak 65f43dbebfSMatan Barak struct uverbs_attr_spec { 66f43dbebfSMatan Barak enum uverbs_attr_type type; 67fac9658cSMatan Barak union { 68fac9658cSMatan Barak u16 len; 69f43dbebfSMatan Barak struct { 70f43dbebfSMatan Barak /* 71f43dbebfSMatan Barak * higher bits mean the namespace and lower bits mean 72f43dbebfSMatan Barak * the type id within the namespace. 73f43dbebfSMatan Barak */ 74f43dbebfSMatan Barak u16 obj_type; 75f43dbebfSMatan Barak u8 access; 76f43dbebfSMatan Barak } obj; 77f43dbebfSMatan Barak }; 78fac9658cSMatan Barak /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */ 79fac9658cSMatan Barak u8 flags; 80fac9658cSMatan Barak }; 81f43dbebfSMatan Barak 82f43dbebfSMatan Barak struct uverbs_attr_spec_hash { 83f43dbebfSMatan Barak size_t num_attrs; 84fac9658cSMatan Barak unsigned long *mandatory_attrs_bitmask; 85f43dbebfSMatan Barak struct uverbs_attr_spec attrs[0]; 86f43dbebfSMatan Barak }; 87f43dbebfSMatan Barak 88fac9658cSMatan Barak struct uverbs_attr_bundle; 89fac9658cSMatan Barak struct ib_uverbs_file; 90fac9658cSMatan Barak 91fac9658cSMatan Barak enum { 92fac9658cSMatan Barak /* 93fac9658cSMatan Barak * Action marked with this flag creates a context (or root for all 94fac9658cSMatan Barak * objects). 95fac9658cSMatan Barak */ 96fac9658cSMatan Barak UVERBS_ACTION_FLAG_CREATE_ROOT = 1U << 0, 97fac9658cSMatan Barak }; 98fac9658cSMatan Barak 99fac9658cSMatan Barak struct uverbs_method_spec { 100fac9658cSMatan Barak /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ 101fac9658cSMatan Barak u32 flags; 102fac9658cSMatan Barak size_t num_buckets; 103fac9658cSMatan Barak size_t num_child_attrs; 104fac9658cSMatan Barak int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, 105fac9658cSMatan Barak struct uverbs_attr_bundle *ctx); 106fac9658cSMatan Barak struct uverbs_attr_spec_hash *attr_buckets[0]; 107fac9658cSMatan Barak }; 108fac9658cSMatan Barak 109fac9658cSMatan Barak struct uverbs_method_spec_hash { 110fac9658cSMatan Barak size_t num_methods; 111fac9658cSMatan Barak struct uverbs_method_spec *methods[0]; 112fac9658cSMatan Barak }; 113fac9658cSMatan Barak 114fac9658cSMatan Barak struct uverbs_object_spec { 115fac9658cSMatan Barak const struct uverbs_obj_type *type_attrs; 116fac9658cSMatan Barak size_t num_buckets; 117fac9658cSMatan Barak struct uverbs_method_spec_hash *method_buckets[0]; 118fac9658cSMatan Barak }; 119fac9658cSMatan Barak 120fac9658cSMatan Barak struct uverbs_object_spec_hash { 121fac9658cSMatan Barak size_t num_objects; 122fac9658cSMatan Barak struct uverbs_object_spec *objects[0]; 123fac9658cSMatan Barak }; 124fac9658cSMatan Barak 125fac9658cSMatan Barak struct uverbs_root_spec { 126fac9658cSMatan Barak size_t num_buckets; 127fac9658cSMatan Barak struct uverbs_object_spec_hash *object_buckets[0]; 128fac9658cSMatan Barak }; 129fac9658cSMatan Barak 1305009010fSMatan Barak /* 1315009010fSMatan Barak * ======================================= 1325009010fSMatan Barak * Verbs definitions 1335009010fSMatan Barak * ======================================= 1345009010fSMatan Barak */ 1355009010fSMatan Barak 13609e3ebf8SMatan Barak struct uverbs_attr_def { 13709e3ebf8SMatan Barak u16 id; 13809e3ebf8SMatan Barak struct uverbs_attr_spec attr; 13909e3ebf8SMatan Barak }; 14009e3ebf8SMatan Barak 14109e3ebf8SMatan Barak struct uverbs_method_def { 14209e3ebf8SMatan Barak u16 id; 14309e3ebf8SMatan Barak /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ 14409e3ebf8SMatan Barak u32 flags; 14509e3ebf8SMatan Barak size_t num_attrs; 14609e3ebf8SMatan Barak const struct uverbs_attr_def * const (*attrs)[]; 14709e3ebf8SMatan Barak int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, 14809e3ebf8SMatan Barak struct uverbs_attr_bundle *ctx); 14909e3ebf8SMatan Barak }; 15009e3ebf8SMatan Barak 1515009010fSMatan Barak struct uverbs_object_def { 15209e3ebf8SMatan Barak u16 id; 1535009010fSMatan Barak const struct uverbs_obj_type *type_attrs; 15409e3ebf8SMatan Barak size_t num_methods; 15509e3ebf8SMatan Barak const struct uverbs_method_def * const (*methods)[]; 15609e3ebf8SMatan Barak }; 15709e3ebf8SMatan Barak 15809e3ebf8SMatan Barak struct uverbs_object_tree_def { 15909e3ebf8SMatan Barak size_t num_objects; 16009e3ebf8SMatan Barak const struct uverbs_object_def * const (*objects)[]; 1615009010fSMatan Barak }; 1625009010fSMatan Barak 1635009010fSMatan Barak #define _UVERBS_OBJECT(_id, _type_attrs, ...) \ 1645009010fSMatan Barak ((const struct uverbs_object_def) { \ 16509e3ebf8SMatan Barak .id = _id, \ 1665009010fSMatan Barak .type_attrs = _type_attrs}) 1675009010fSMatan Barak #define DECLARE_UVERBS_OBJECT(_name, _id, _type_attrs, ...) \ 1685009010fSMatan Barak const struct uverbs_object_def _name = \ 1695009010fSMatan Barak _UVERBS_OBJECT(_id, _type_attrs, ##__VA_ARGS__) 17009e3ebf8SMatan Barak #define _UVERBS_TREE_OBJECTS_SZ(...) \ 17109e3ebf8SMatan Barak (sizeof((const struct uverbs_object_def * const []){__VA_ARGS__}) / \ 17209e3ebf8SMatan Barak sizeof(const struct uverbs_object_def *)) 17309e3ebf8SMatan Barak #define _UVERBS_OBJECT_TREE(...) \ 17409e3ebf8SMatan Barak ((const struct uverbs_object_tree_def) { \ 17509e3ebf8SMatan Barak .num_objects = _UVERBS_TREE_OBJECTS_SZ(__VA_ARGS__), \ 17609e3ebf8SMatan Barak .objects = &(const struct uverbs_object_def * const []){__VA_ARGS__} }) 17709e3ebf8SMatan Barak #define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \ 17809e3ebf8SMatan Barak const struct uverbs_object_tree_def _name = \ 17909e3ebf8SMatan Barak _UVERBS_OBJECT_TREE(__VA_ARGS__) 18009e3ebf8SMatan Barak 181fac9658cSMatan Barak /* ================================================= 182fac9658cSMatan Barak * Parsing infrastructure 183fac9658cSMatan Barak * ================================================= 184fac9658cSMatan Barak */ 185fac9658cSMatan Barak 186fac9658cSMatan Barak struct uverbs_ptr_attr { 187fac9658cSMatan Barak union { 188fac9658cSMatan Barak u64 data; 189fac9658cSMatan Barak void __user *ptr; 190fac9658cSMatan Barak }; 191fac9658cSMatan Barak u16 len; 192fac9658cSMatan Barak /* Combination of bits from enum UVERBS_ATTR_F_XXXX */ 193fac9658cSMatan Barak u16 flags; 194fac9658cSMatan Barak }; 195fac9658cSMatan Barak 196f43dbebfSMatan Barak struct uverbs_obj_attr { 197fac9658cSMatan Barak /* pointer to the kernel descriptor -> type, access, etc */ 198fac9658cSMatan Barak const struct uverbs_obj_type *type; 199f43dbebfSMatan Barak struct ib_uobject *uobject; 200fac9658cSMatan Barak /* fd or id in idr of this object */ 201fac9658cSMatan Barak int id; 202f43dbebfSMatan Barak }; 203f43dbebfSMatan Barak 204f43dbebfSMatan Barak struct uverbs_attr { 205fac9658cSMatan Barak /* 206fac9658cSMatan Barak * pointer to the user-space given attribute, in order to write the 207fac9658cSMatan Barak * new uobject's id or update flags. 208fac9658cSMatan Barak */ 209fac9658cSMatan Barak struct ib_uverbs_attr __user *uattr; 210fac9658cSMatan Barak union { 211fac9658cSMatan Barak struct uverbs_ptr_attr ptr_attr; 212f43dbebfSMatan Barak struct uverbs_obj_attr obj_attr; 213f43dbebfSMatan Barak }; 214fac9658cSMatan Barak }; 215f43dbebfSMatan Barak 216f43dbebfSMatan Barak struct uverbs_attr_bundle_hash { 217f43dbebfSMatan Barak /* if bit i is set, it means attrs[i] contains valid information */ 218f43dbebfSMatan Barak unsigned long *valid_bitmap; 219f43dbebfSMatan Barak size_t num_attrs; 220f43dbebfSMatan Barak /* 221f43dbebfSMatan Barak * arrays of attributes, each element corresponds to the specification 222f43dbebfSMatan Barak * of the attribute in the same index. 223f43dbebfSMatan Barak */ 224f43dbebfSMatan Barak struct uverbs_attr *attrs; 225f43dbebfSMatan Barak }; 226f43dbebfSMatan Barak 227f43dbebfSMatan Barak struct uverbs_attr_bundle { 228f43dbebfSMatan Barak size_t num_buckets; 229f43dbebfSMatan Barak struct uverbs_attr_bundle_hash hash[]; 230f43dbebfSMatan Barak }; 231f43dbebfSMatan Barak 232f43dbebfSMatan Barak static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash, 233f43dbebfSMatan Barak unsigned int idx) 234f43dbebfSMatan Barak { 235f43dbebfSMatan Barak return test_bit(idx, attrs_hash->valid_bitmap); 236f43dbebfSMatan Barak } 237f43dbebfSMatan Barak 238*118620d3SMatan Barak /* ================================================= 239*118620d3SMatan Barak * Definitions -> Specs infrastructure 240*118620d3SMatan Barak * ================================================= 241*118620d3SMatan Barak */ 242a0aa309cSMatan Barak 243*118620d3SMatan Barak /* 244*118620d3SMatan Barak * uverbs_alloc_spec_tree - Merges different common and driver specific feature 245*118620d3SMatan Barak * into one parsing tree that every uverbs command will be parsed upon. 246*118620d3SMatan Barak * 247*118620d3SMatan Barak * @num_trees: Number of trees in the array @trees. 248*118620d3SMatan Barak * @trees: Array of pointers to tree root definitions to merge. Each such tree 249*118620d3SMatan Barak * possibly contains objects, methods and attributes definitions. 250*118620d3SMatan Barak * 251*118620d3SMatan Barak * Returns: 252*118620d3SMatan Barak * uverbs_root_spec *: The root of the merged parsing tree. 253*118620d3SMatan Barak * On error, we return an error code. Error is checked via IS_ERR. 254*118620d3SMatan Barak * 255*118620d3SMatan Barak * The following merges could take place: 256*118620d3SMatan Barak * a. Two trees representing the same method with different handler 257*118620d3SMatan Barak * -> We take the handler of the tree that its handler != NULL 258*118620d3SMatan Barak * and its index in the trees array is greater. The incentive for that 259*118620d3SMatan Barak * is that developers are expected to first merge common trees and then 260*118620d3SMatan Barak * merge trees that gives specialized the behaviour. 261*118620d3SMatan Barak * b. Two trees representing the same object with different 262*118620d3SMatan Barak * type_attrs (struct uverbs_obj_type): 263*118620d3SMatan Barak * -> We take the type_attrs of the tree that its type_attr != NULL 264*118620d3SMatan Barak * and its index in the trees array is greater. This could be used 265*118620d3SMatan Barak * in order to override the free function, allocation size, etc. 266*118620d3SMatan Barak * c. Two trees representing the same method attribute (same id but possibly 267*118620d3SMatan Barak * different attributes): 268*118620d3SMatan Barak * -> ERROR (-ENOENT), we believe that's not the programmer's intent. 269*118620d3SMatan Barak * 270*118620d3SMatan Barak * An object without any methods is considered invalid and will abort the 271*118620d3SMatan Barak * function with -ENOENT error. 272*118620d3SMatan Barak */ 273*118620d3SMatan Barak struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, 274*118620d3SMatan Barak const struct uverbs_object_tree_def **trees); 275*118620d3SMatan Barak void uverbs_free_spec_tree(struct uverbs_root_spec *root); 276*118620d3SMatan Barak 277*118620d3SMatan Barak #endif 278