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 | 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(error: -ENOMSG); |
137 | |
138 | res = radix_tree_lookup(&uapi->radix, uapi_key_obj(id: object_id)); |
139 | if (!res) |
140 | return ERR_PTR(error: -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_obj_qp[]; |
163 | extern const struct uapi_definition uverbs_def_obj_srq[]; |
164 | extern const struct uapi_definition uverbs_def_obj_wq[]; |
165 | extern const struct uapi_definition uverbs_def_write_intf[]; |
166 | |
167 | static inline const struct uverbs_api_write_method * |
168 | uapi_get_method(const struct uverbs_api *uapi, u32 command) |
169 | { |
170 | u32 cmd_idx = command & IB_USER_VERBS_CMD_COMMAND_MASK; |
171 | |
172 | if (command & ~(u32)(IB_USER_VERBS_CMD_FLAG_EXTENDED | |
173 | IB_USER_VERBS_CMD_COMMAND_MASK)) |
174 | return ERR_PTR(error: -EINVAL); |
175 | |
176 | if (command & IB_USER_VERBS_CMD_FLAG_EXTENDED) { |
177 | if (cmd_idx >= uapi->num_write_ex) |
178 | return ERR_PTR(error: -EOPNOTSUPP); |
179 | return uapi->write_ex_methods[cmd_idx]; |
180 | } |
181 | |
182 | if (cmd_idx >= uapi->num_write) |
183 | return ERR_PTR(error: -EOPNOTSUPP); |
184 | return uapi->write_methods[cmd_idx]; |
185 | } |
186 | |
187 | void uverbs_fill_udata(struct uverbs_attr_bundle *bundle, |
188 | struct ib_udata *udata, unsigned int attr_in, |
189 | unsigned int attr_out); |
190 | |
191 | #endif /* RDMA_CORE_H */ |
192 | |