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 commit, 68 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 void release_ufile_idr_uobject(struct ib_uverbs_file *ufile); 74 75 struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs); 76 77 /* 78 * This is the runtime description of the uverbs API, used by the syscall 79 * machinery to validate and dispatch calls. 80 */ 81 82 /* 83 * Depending on ID the slot pointer in the radix tree points at one of these 84 * structs. 85 */ 86 87 struct uverbs_api_ioctl_method { 88 int(__rcu *handler)(struct uverbs_attr_bundle *attrs); 89 DECLARE_BITMAP(attr_mandatory, UVERBS_API_ATTR_BKEY_LEN); 90 u16 bundle_size; 91 u8 use_stack:1; 92 u8 driver_method:1; 93 u8 disabled:1; 94 u8 has_udata:1; 95 u8 key_bitmap_len; 96 u8 destroy_bkey; 97 }; 98 99 struct uverbs_api_write_method { 100 int (*handler)(struct uverbs_attr_bundle *attrs); 101 u8 disabled:1; 102 u8 is_ex:1; 103 u8 has_udata:1; 104 u8 has_resp:1; 105 u8 req_size; 106 u8 resp_size; 107 }; 108 109 struct uverbs_api_attr { 110 struct uverbs_attr_spec spec; 111 }; 112 113 struct uverbs_api { 114 /* radix tree contains struct uverbs_api_* pointers */ 115 struct radix_tree_root radix; 116 enum rdma_driver_id driver_id; 117 118 unsigned int num_write; 119 unsigned int num_write_ex; 120 struct uverbs_api_write_method notsupp_method; 121 const struct uverbs_api_write_method **write_methods; 122 const struct uverbs_api_write_method **write_ex_methods; 123 }; 124 125 /* 126 * Get an uverbs_api_object that corresponds to the given object_id. 127 * Note: 128 * -ENOMSG means that any object is allowed to match during lookup. 129 */ 130 static inline const struct uverbs_api_object * 131 uapi_get_object(struct uverbs_api *uapi, u16 object_id) 132 { 133 const struct uverbs_api_object *res; 134 135 if (object_id == UVERBS_IDR_ANY_OBJECT) 136 return ERR_PTR(-ENOMSG); 137 138 res = radix_tree_lookup(&uapi->radix, uapi_key_obj(object_id)); 139 if (!res) 140 return ERR_PTR(-ENOENT); 141 142 return res; 143 } 144 145 char *uapi_key_format(char *S, unsigned int key); 146 struct uverbs_api *uverbs_alloc_api(struct ib_device *ibdev); 147 void uverbs_disassociate_api_pre(struct ib_uverbs_device *uverbs_dev); 148 void uverbs_disassociate_api(struct uverbs_api *uapi); 149 void uverbs_destroy_api(struct uverbs_api *uapi); 150 void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm, 151 unsigned int num_attrs); 152 void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile); 153 154 extern const struct uapi_definition uverbs_def_obj_async_fd[]; 155 extern const struct uapi_definition uverbs_def_obj_counters[]; 156 extern const struct uapi_definition uverbs_def_obj_cq[]; 157 extern const struct uapi_definition uverbs_def_obj_device[]; 158 extern const struct uapi_definition uverbs_def_obj_dm[]; 159 extern const struct uapi_definition uverbs_def_obj_flow_action[]; 160 extern const struct uapi_definition uverbs_def_obj_intf[]; 161 extern const struct uapi_definition uverbs_def_obj_mr[]; 162 extern const struct uapi_definition uverbs_def_write_intf[]; 163 164 static inline const struct uverbs_api_write_method * 165 uapi_get_method(const struct uverbs_api *uapi, u32 command) 166 { 167 u32 cmd_idx = command & IB_USER_VERBS_CMD_COMMAND_MASK; 168 169 if (command & ~(u32)(IB_USER_VERBS_CMD_FLAG_EXTENDED | 170 IB_USER_VERBS_CMD_COMMAND_MASK)) 171 return ERR_PTR(-EINVAL); 172 173 if (command & IB_USER_VERBS_CMD_FLAG_EXTENDED) { 174 if (cmd_idx >= uapi->num_write_ex) 175 return ERR_PTR(-EOPNOTSUPP); 176 return uapi->write_ex_methods[cmd_idx]; 177 } 178 179 if (cmd_idx >= uapi->num_write) 180 return ERR_PTR(-EOPNOTSUPP); 181 return uapi->write_methods[cmd_idx]; 182 } 183 184 void uverbs_fill_udata(struct uverbs_attr_bundle *bundle, 185 struct ib_udata *udata, unsigned int attr_in, 186 unsigned int attr_out); 187 188 #endif /* RDMA_CORE_H */ 189