1 /* 2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 3 * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. 4 * Copyright (c) 2005-2017 Mellanox Technologies. All rights reserved. 5 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 6 * Copyright (c) 2005 PathScale, Inc. All rights reserved. 7 * 8 * This software is available to you under a choice of one of two 9 * licenses. You may choose to be licensed under the terms of the GNU 10 * General Public License (GPL) Version 2, available from the file 11 * COPYING in the main directory of this source tree, or the 12 * OpenIB.org BSD license below: 13 * 14 * Redistribution and use in source and binary forms, with or 15 * without modification, are permitted provided that the following 16 * conditions are met: 17 * 18 * - Redistributions of source code must retain the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer. 21 * 22 * - Redistributions in binary form must reproduce the above 23 * copyright notice, this list of conditions and the following 24 * disclaimer in the documentation and/or other materials 25 * provided with the distribution. 26 * 27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 * SOFTWARE. 35 */ 36 37 #ifndef RDMA_CORE_H 38 #define RDMA_CORE_H 39 40 #include <linux/idr.h> 41 #include <linux/radix-tree.h> 42 #include <rdma/uverbs_types.h> 43 #include <rdma/uverbs_ioctl.h> 44 #include <rdma/ib_verbs.h> 45 #include <linux/mutex.h> 46 47 struct ib_uverbs_device; 48 49 void uverbs_destroy_ufile_hw(struct ib_uverbs_file *ufile, 50 enum rdma_remove_reason reason); 51 52 int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs); 53 54 /* 55 * Get an ib_uobject that corresponds to the given id from ufile, assuming 56 * the object is from the given type. Lock it to the required access when 57 * applicable. 58 * This function could create (access == NEW), destroy (access == DESTROY) 59 * or unlock (access == READ || access == WRITE) objects if required. 60 * The action will be finalized only when uverbs_finalize_object or 61 * uverbs_finalize_objects are called. 62 */ 63 struct ib_uobject * 64 uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access, 65 s64 id, struct uverbs_attr_bundle *attrs); 66 67 void uverbs_finalize_object(struct ib_uobject *uobj, 68 enum uverbs_obj_access access, bool commit, 69 struct uverbs_attr_bundle *attrs); 70 71 int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx); 72 73 void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile); 74 void release_ufile_idr_uobject(struct ib_uverbs_file *ufile); 75 76 struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs); 77 78 /* 79 * This is the runtime description of the uverbs API, used by the syscall 80 * machinery to validate and dispatch calls. 81 */ 82 83 /* 84 * Depending on ID the slot pointer in the radix tree points at one of these 85 * structs. 86 */ 87 88 struct uverbs_api_ioctl_method { 89 int(__rcu *handler)(struct uverbs_attr_bundle *attrs); 90 DECLARE_BITMAP(attr_mandatory, UVERBS_API_ATTR_BKEY_LEN); 91 u16 bundle_size; 92 u8 use_stack:1; 93 u8 driver_method:1; 94 u8 disabled:1; 95 u8 has_udata:1; 96 u8 key_bitmap_len; 97 u8 destroy_bkey; 98 }; 99 100 struct uverbs_api_write_method { 101 int (*handler)(struct uverbs_attr_bundle *attrs); 102 u8 disabled:1; 103 u8 is_ex:1; 104 u8 has_udata:1; 105 u8 has_resp:1; 106 u8 req_size; 107 u8 resp_size; 108 }; 109 110 struct uverbs_api_attr { 111 struct uverbs_attr_spec spec; 112 }; 113 114 struct uverbs_api { 115 /* radix tree contains struct uverbs_api_* pointers */ 116 struct radix_tree_root radix; 117 enum rdma_driver_id driver_id; 118 119 unsigned int num_write; 120 unsigned int num_write_ex; 121 struct uverbs_api_write_method notsupp_method; 122 const struct uverbs_api_write_method **write_methods; 123 const struct uverbs_api_write_method **write_ex_methods; 124 }; 125 126 /* 127 * Get an uverbs_api_object that corresponds to the given object_id. 128 * Note: 129 * -ENOMSG means that any object is allowed to match during lookup. 130 */ 131 static inline const struct uverbs_api_object * 132 uapi_get_object(struct uverbs_api *uapi, u16 object_id) 133 { 134 const struct uverbs_api_object *res; 135 136 if (object_id == UVERBS_IDR_ANY_OBJECT) 137 return ERR_PTR(-ENOMSG); 138 139 res = radix_tree_lookup(&uapi->radix, uapi_key_obj(object_id)); 140 if (!res) 141 return ERR_PTR(-ENOENT); 142 143 return res; 144 } 145 146 char *uapi_key_format(char *S, unsigned int key); 147 struct uverbs_api *uverbs_alloc_api(struct ib_device *ibdev); 148 void uverbs_disassociate_api_pre(struct ib_uverbs_device *uverbs_dev); 149 void uverbs_disassociate_api(struct uverbs_api *uapi); 150 void uverbs_destroy_api(struct uverbs_api *uapi); 151 void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm, 152 unsigned int num_attrs); 153 void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile); 154 155 extern const struct uapi_definition uverbs_def_obj_async_fd[]; 156 extern const struct uapi_definition uverbs_def_obj_counters[]; 157 extern const struct uapi_definition uverbs_def_obj_cq[]; 158 extern const struct uapi_definition uverbs_def_obj_device[]; 159 extern const struct uapi_definition uverbs_def_obj_dm[]; 160 extern const struct uapi_definition uverbs_def_obj_flow_action[]; 161 extern const struct uapi_definition uverbs_def_obj_intf[]; 162 extern const struct uapi_definition uverbs_def_obj_mr[]; 163 extern const struct uapi_definition uverbs_def_write_intf[]; 164 165 static inline const struct uverbs_api_write_method * 166 uapi_get_method(const struct uverbs_api *uapi, u32 command) 167 { 168 u32 cmd_idx = command & IB_USER_VERBS_CMD_COMMAND_MASK; 169 170 if (command & ~(u32)(IB_USER_VERBS_CMD_FLAG_EXTENDED | 171 IB_USER_VERBS_CMD_COMMAND_MASK)) 172 return ERR_PTR(-EINVAL); 173 174 if (command & IB_USER_VERBS_CMD_FLAG_EXTENDED) { 175 if (cmd_idx >= uapi->num_write_ex) 176 return ERR_PTR(-EOPNOTSUPP); 177 return uapi->write_ex_methods[cmd_idx]; 178 } 179 180 if (cmd_idx >= uapi->num_write) 181 return ERR_PTR(-EOPNOTSUPP); 182 return uapi->write_methods[cmd_idx]; 183 } 184 185 void uverbs_fill_udata(struct uverbs_attr_bundle *bundle, 186 struct ib_udata *udata, unsigned int attr_in, 187 unsigned int attr_out); 188 189 #endif /* RDMA_CORE_H */ 190