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 <rdma/uverbs_types.h> 42 #include <rdma/uverbs_ioctl.h> 43 #include <rdma/ib_verbs.h> 44 #include <linux/mutex.h> 45 46 struct ib_uverbs_device; 47 48 void uverbs_destroy_ufile_hw(struct ib_uverbs_file *ufile, 49 enum rdma_remove_reason reason); 50 51 int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs); 52 53 /* 54 * Get an ib_uobject that corresponds to the given id from ufile, assuming 55 * the object is from the given type. Lock it to the required access when 56 * applicable. 57 * This function could create (access == NEW), destroy (access == DESTROY) 58 * or unlock (access == READ || access == WRITE) objects if required. 59 * The action will be finalized only when uverbs_finalize_object or 60 * uverbs_finalize_objects are called. 61 */ 62 struct ib_uobject * 63 uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access, 64 s64 id, struct uverbs_attr_bundle *attrs); 65 66 void uverbs_finalize_object(struct ib_uobject *uobj, 67 enum uverbs_obj_access access, bool hw_obj_valid, 68 bool commit, struct uverbs_attr_bundle *attrs); 69 70 int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx); 71 72 void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile); 73 74 #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) 75 struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs); 76 #else 77 static inline struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs) 78 { 79 return NULL; 80 } 81 #endif 82 83 /* 84 * This is the runtime description of the uverbs API, used by the syscall 85 * machinery to validate and dispatch calls. 86 */ 87 88 /* 89 * Depending on ID the slot pointer in the radix tree points at one of these 90 * structs. 91 */ 92 93 struct uverbs_api_ioctl_method { 94 int(__rcu *handler)(struct uverbs_attr_bundle *attrs); 95 DECLARE_BITMAP(attr_mandatory, UVERBS_API_ATTR_BKEY_LEN); 96 u16 bundle_size; 97 u8 use_stack:1; 98 u8 driver_method:1; 99 u8 disabled:1; 100 u8 has_udata:1; 101 u8 key_bitmap_len; 102 u8 destroy_bkey; 103 }; 104 105 struct uverbs_api_write_method { 106 int (*handler)(struct uverbs_attr_bundle *attrs); 107 u8 disabled:1; 108 u8 is_ex:1; 109 u8 has_udata:1; 110 u8 has_resp:1; 111 u8 req_size; 112 u8 resp_size; 113 }; 114 115 struct uverbs_api_attr { 116 struct uverbs_attr_spec spec; 117 }; 118 119 struct uverbs_api { 120 /* radix tree contains struct uverbs_api_* pointers */ 121 struct radix_tree_root radix; 122 enum rdma_driver_id driver_id; 123 124 unsigned int num_write; 125 unsigned int num_write_ex; 126 struct uverbs_api_write_method notsupp_method; 127 const struct uverbs_api_write_method **write_methods; 128 const struct uverbs_api_write_method **write_ex_methods; 129 }; 130 131 /* 132 * Get an uverbs_api_object that corresponds to the given object_id. 133 * Note: 134 * -ENOMSG means that any object is allowed to match during lookup. 135 */ 136 static inline const struct uverbs_api_object * 137 uapi_get_object(struct uverbs_api *uapi, u16 object_id) 138 { 139 const struct uverbs_api_object *res; 140 141 if (object_id == UVERBS_IDR_ANY_OBJECT) 142 return ERR_PTR(-ENOMSG); 143 144 res = radix_tree_lookup(&uapi->radix, uapi_key_obj(object_id)); 145 if (!res) 146 return ERR_PTR(-ENOENT); 147 148 return res; 149 } 150 151 char *uapi_key_format(char *S, unsigned int key); 152 struct uverbs_api *uverbs_alloc_api(struct ib_device *ibdev); 153 void uverbs_disassociate_api_pre(struct ib_uverbs_device *uverbs_dev); 154 void uverbs_disassociate_api(struct uverbs_api *uapi); 155 void uverbs_destroy_api(struct uverbs_api *uapi); 156 void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm, 157 unsigned int num_attrs); 158 void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile); 159 160 extern const struct uapi_definition uverbs_def_obj_async_fd[]; 161 extern const struct uapi_definition uverbs_def_obj_counters[]; 162 extern const struct uapi_definition uverbs_def_obj_cq[]; 163 extern const struct uapi_definition uverbs_def_obj_device[]; 164 extern const struct uapi_definition uverbs_def_obj_dm[]; 165 extern const struct uapi_definition uverbs_def_obj_dmabuf[]; 166 extern const struct uapi_definition uverbs_def_obj_dmah[]; 167 extern const struct uapi_definition uverbs_def_obj_flow_action[]; 168 extern const struct uapi_definition uverbs_def_obj_intf[]; 169 extern const struct uapi_definition uverbs_def_obj_mr[]; 170 extern const struct uapi_definition uverbs_def_obj_qp[]; 171 extern const struct uapi_definition uverbs_def_obj_srq[]; 172 extern const struct uapi_definition uverbs_def_obj_wq[]; 173 extern const struct uapi_definition uverbs_def_write_intf[]; 174 175 static inline const struct uverbs_api_write_method * 176 uapi_get_method(const struct uverbs_api *uapi, u32 command) 177 { 178 u32 cmd_idx = command & IB_USER_VERBS_CMD_COMMAND_MASK; 179 180 if (command & ~(u32)(IB_USER_VERBS_CMD_FLAG_EXTENDED | 181 IB_USER_VERBS_CMD_COMMAND_MASK)) 182 return ERR_PTR(-EINVAL); 183 184 if (command & IB_USER_VERBS_CMD_FLAG_EXTENDED) { 185 if (cmd_idx >= uapi->num_write_ex) 186 return ERR_PTR(-EOPNOTSUPP); 187 return uapi->write_ex_methods[cmd_idx]; 188 } 189 190 if (cmd_idx >= uapi->num_write) 191 return ERR_PTR(-EOPNOTSUPP); 192 return uapi->write_methods[cmd_idx]; 193 } 194 195 void uverbs_fill_udata(struct uverbs_attr_bundle *bundle, 196 struct ib_udata *udata, unsigned int attr_in, 197 unsigned int attr_out); 198 199 #endif /* RDMA_CORE_H */ 200