blob: 0aa2ee732eaa58b0d7d7cb456b70d96330d316d9 [file] [log] [blame]
Yishai Hadasa8b92ca2018-06-17 12:59:57 +03001// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/*
3 * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
4 */
5
6#include <rdma/ib_user_verbs.h>
7#include <rdma/ib_verbs.h>
8#include <rdma/uverbs_types.h>
9#include <rdma/uverbs_ioctl.h>
10#include <rdma/mlx5_user_ioctl_cmds.h>
11#include <rdma/ib_umem.h>
12#include <linux/mlx5/driver.h>
13#include <linux/mlx5/fs.h>
14#include "mlx5_ib.h"
15
Yishai Hadas8aa8c952018-06-17 13:00:00 +030016#define UVERBS_MODULE_NAME mlx5_ib
17#include <rdma/uverbs_named_ioctl.h>
18
Yishai Hadas7efce362018-06-17 13:00:01 +030019#define MLX5_MAX_DESTROY_INBOX_SIZE_DW MLX5_ST_SZ_DW(delete_fte_in)
20struct devx_obj {
21 struct mlx5_core_dev *mdev;
Yishai Hadas2351776e2018-10-07 12:06:34 +030022 u64 obj_id;
Yishai Hadas7efce362018-06-17 13:00:01 +030023 u32 dinlen; /* destroy inbox length */
24 u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
25};
26
Yishai Hadasaeae9452018-06-17 13:00:04 +030027struct devx_umem {
28 struct mlx5_core_dev *mdev;
29 struct ib_umem *umem;
30 u32 page_offset;
31 int page_shift;
32 int ncont;
33 u32 dinlen;
34 u32 dinbox[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)];
35};
36
37struct devx_umem_reg_cmd {
38 void *in;
39 u32 inlen;
40 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
41};
42
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +020043static struct mlx5_ib_ucontext *
44devx_ufile2uctx(const struct uverbs_attr_bundle *attrs)
Yishai Hadas8aa8c952018-06-17 13:00:00 +030045{
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +020046 return to_mucontext(ib_uverbs_get_ucontext(attrs));
Yishai Hadas8aa8c952018-06-17 13:00:00 +030047}
48
Yishai Hadas76dc5a82018-09-20 21:45:19 +030049int mlx5_ib_devx_create(struct mlx5_ib_dev *dev)
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030050{
51 u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0};
52 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
53 u64 general_obj_types;
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030054 void *hdr;
55 int err;
Yishai Hadas76dc5a82018-09-20 21:45:19 +030056 u16 uid;
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030057
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030058 hdr = MLX5_ADDR_OF(create_uctx_in, in, hdr);
59
60 general_obj_types = MLX5_CAP_GEN_64(dev->mdev, general_obj_types);
61 if (!(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UCTX) ||
62 !(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UMEM))
63 return -EINVAL;
64
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030065 MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
66 MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, MLX5_OBJ_TYPE_UCTX);
67
68 err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
69 if (err)
70 return err;
71
Yishai Hadas76dc5a82018-09-20 21:45:19 +030072 uid = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
73 return uid;
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030074}
75
Yishai Hadas76dc5a82018-09-20 21:45:19 +030076void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid)
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030077{
78 u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
79 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
80
81 MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
82 MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_UCTX);
Yishai Hadas76dc5a82018-09-20 21:45:19 +030083 MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, uid);
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030084
85 mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
86}
Yishai Hadas8aa8c952018-06-17 13:00:00 +030087
Yishai Hadas32269442018-07-23 15:25:09 +030088bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type)
89{
90 struct devx_obj *devx_obj = obj;
91 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
92
93 switch (opcode) {
94 case MLX5_CMD_OP_DESTROY_TIR:
95 *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR;
96 *dest_id = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox,
97 obj_id);
98 return true;
99
100 case MLX5_CMD_OP_DESTROY_FLOW_TABLE:
101 *dest_type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
102 *dest_id = MLX5_GET(destroy_flow_table_in, devx_obj->dinbox,
103 table_id);
104 return true;
105 default:
106 return false;
107 }
108}
109
Mark Blochbfc5d832018-11-20 20:31:08 +0200110bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id)
111{
112 struct devx_obj *devx_obj = obj;
113 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
114
115 if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) {
116 *counter_id = MLX5_GET(dealloc_flow_counter_in,
117 devx_obj->dinbox,
118 flow_counter_id);
119 return true;
120 }
121
122 return false;
123}
124
Yishai Hadas2351776e2018-10-07 12:06:34 +0300125/*
126 * As the obj_id in the firmware is not globally unique the object type
127 * must be considered upon checking for a valid object id.
128 * For that the opcode of the creator command is encoded as part of the obj_id.
129 */
130static u64 get_enc_obj_id(u16 opcode, u32 obj_id)
131{
132 return ((u64)opcode << 32) | obj_id;
133}
134
Yishai Hadase662e142018-06-17 13:00:02 +0300135static int devx_is_valid_obj_id(struct devx_obj *obj, const void *in)
136{
137 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
Yishai Hadas2351776e2018-10-07 12:06:34 +0300138 u64 obj_id;
Yishai Hadase662e142018-06-17 13:00:02 +0300139
140 switch (opcode) {
141 case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
142 case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300143 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_GENERAL_OBJECT,
144 MLX5_GET(general_obj_in_cmd_hdr, in,
145 obj_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300146 break;
147 case MLX5_CMD_OP_QUERY_MKEY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300148 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_MKEY,
149 MLX5_GET(query_mkey_in, in,
150 mkey_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300151 break;
152 case MLX5_CMD_OP_QUERY_CQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300153 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ,
154 MLX5_GET(query_cq_in, in, cqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300155 break;
156 case MLX5_CMD_OP_MODIFY_CQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300157 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ,
158 MLX5_GET(modify_cq_in, in, cqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300159 break;
160 case MLX5_CMD_OP_QUERY_SQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300161 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ,
162 MLX5_GET(query_sq_in, in, sqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300163 break;
164 case MLX5_CMD_OP_MODIFY_SQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300165 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ,
166 MLX5_GET(modify_sq_in, in, sqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300167 break;
168 case MLX5_CMD_OP_QUERY_RQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300169 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
170 MLX5_GET(query_rq_in, in, rqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300171 break;
172 case MLX5_CMD_OP_MODIFY_RQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300173 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
174 MLX5_GET(modify_rq_in, in, rqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300175 break;
176 case MLX5_CMD_OP_QUERY_RMP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300177 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP,
178 MLX5_GET(query_rmp_in, in, rmpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300179 break;
180 case MLX5_CMD_OP_MODIFY_RMP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300181 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP,
182 MLX5_GET(modify_rmp_in, in, rmpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300183 break;
184 case MLX5_CMD_OP_QUERY_RQT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300185 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT,
186 MLX5_GET(query_rqt_in, in, rqtn));
Yishai Hadase662e142018-06-17 13:00:02 +0300187 break;
188 case MLX5_CMD_OP_MODIFY_RQT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300189 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT,
190 MLX5_GET(modify_rqt_in, in, rqtn));
Yishai Hadase662e142018-06-17 13:00:02 +0300191 break;
192 case MLX5_CMD_OP_QUERY_TIR:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300193 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR,
194 MLX5_GET(query_tir_in, in, tirn));
Yishai Hadase662e142018-06-17 13:00:02 +0300195 break;
196 case MLX5_CMD_OP_MODIFY_TIR:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300197 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR,
198 MLX5_GET(modify_tir_in, in, tirn));
Yishai Hadase662e142018-06-17 13:00:02 +0300199 break;
200 case MLX5_CMD_OP_QUERY_TIS:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300201 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS,
202 MLX5_GET(query_tis_in, in, tisn));
Yishai Hadase662e142018-06-17 13:00:02 +0300203 break;
204 case MLX5_CMD_OP_MODIFY_TIS:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300205 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS,
206 MLX5_GET(modify_tis_in, in, tisn));
Yishai Hadase662e142018-06-17 13:00:02 +0300207 break;
208 case MLX5_CMD_OP_QUERY_FLOW_TABLE:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300209 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE,
210 MLX5_GET(query_flow_table_in, in,
211 table_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300212 break;
213 case MLX5_CMD_OP_MODIFY_FLOW_TABLE:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300214 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE,
215 MLX5_GET(modify_flow_table_in, in,
216 table_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300217 break;
218 case MLX5_CMD_OP_QUERY_FLOW_GROUP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300219 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_GROUP,
220 MLX5_GET(query_flow_group_in, in,
221 group_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300222 break;
223 case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300224 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY,
225 MLX5_GET(query_fte_in, in,
226 flow_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300227 break;
228 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300229 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY,
230 MLX5_GET(set_fte_in, in, flow_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300231 break;
232 case MLX5_CMD_OP_QUERY_Q_COUNTER:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300233 obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_Q_COUNTER,
234 MLX5_GET(query_q_counter_in, in,
235 counter_set_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300236 break;
237 case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300238 obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_FLOW_COUNTER,
239 MLX5_GET(query_flow_counter_in, in,
240 flow_counter_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300241 break;
242 case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300243 obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT,
244 MLX5_GET(general_obj_in_cmd_hdr, in,
245 obj_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300246 break;
247 case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300248 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT,
249 MLX5_GET(query_scheduling_element_in,
250 in, scheduling_element_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300251 break;
252 case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300253 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT,
254 MLX5_GET(modify_scheduling_element_in,
255 in, scheduling_element_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300256 break;
257 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300258 obj_id = get_enc_obj_id(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT,
259 MLX5_GET(add_vxlan_udp_dport_in, in,
260 vxlan_udp_port));
Yishai Hadase662e142018-06-17 13:00:02 +0300261 break;
262 case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300263 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY,
264 MLX5_GET(query_l2_table_entry_in, in,
265 table_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300266 break;
267 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300268 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY,
269 MLX5_GET(set_l2_table_entry_in, in,
270 table_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300271 break;
272 case MLX5_CMD_OP_QUERY_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300273 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
274 MLX5_GET(query_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300275 break;
276 case MLX5_CMD_OP_RST2INIT_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300277 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
278 MLX5_GET(rst2init_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300279 break;
280 case MLX5_CMD_OP_INIT2RTR_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300281 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
282 MLX5_GET(init2rtr_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300283 break;
284 case MLX5_CMD_OP_RTR2RTS_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300285 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
286 MLX5_GET(rtr2rts_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300287 break;
288 case MLX5_CMD_OP_RTS2RTS_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300289 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
290 MLX5_GET(rts2rts_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300291 break;
292 case MLX5_CMD_OP_SQERR2RTS_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300293 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
294 MLX5_GET(sqerr2rts_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300295 break;
296 case MLX5_CMD_OP_2ERR_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300297 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
298 MLX5_GET(qp_2err_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300299 break;
300 case MLX5_CMD_OP_2RST_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300301 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
302 MLX5_GET(qp_2rst_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300303 break;
304 case MLX5_CMD_OP_QUERY_DCT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300305 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
306 MLX5_GET(query_dct_in, in, dctn));
Yishai Hadase662e142018-06-17 13:00:02 +0300307 break;
308 case MLX5_CMD_OP_QUERY_XRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300309 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ,
310 MLX5_GET(query_xrq_in, in, xrqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300311 break;
312 case MLX5_CMD_OP_QUERY_XRC_SRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300313 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ,
314 MLX5_GET(query_xrc_srq_in, in,
315 xrc_srqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300316 break;
317 case MLX5_CMD_OP_ARM_XRC_SRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300318 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ,
319 MLX5_GET(arm_xrc_srq_in, in, xrc_srqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300320 break;
321 case MLX5_CMD_OP_QUERY_SRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300322 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SRQ,
323 MLX5_GET(query_srq_in, in, srqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300324 break;
325 case MLX5_CMD_OP_ARM_RQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300326 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
327 MLX5_GET(arm_rq_in, in, srq_number));
Yishai Hadase662e142018-06-17 13:00:02 +0300328 break;
329 case MLX5_CMD_OP_DRAIN_DCT:
330 case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300331 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
332 MLX5_GET(drain_dct_in, in, dctn));
Yishai Hadase662e142018-06-17 13:00:02 +0300333 break;
334 case MLX5_CMD_OP_ARM_XRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300335 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ,
336 MLX5_GET(arm_xrq_in, in, xrqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300337 break;
338 default:
339 return false;
340 }
341
342 if (obj_id == obj->obj_id)
343 return true;
344
345 return false;
346}
347
Yishai Hadasba1a0572018-09-20 21:39:33 +0300348static void devx_set_umem_valid(const void *in)
349{
350 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
351
352 switch (opcode) {
353 case MLX5_CMD_OP_CREATE_MKEY:
354 MLX5_SET(create_mkey_in, in, mkey_umem_valid, 1);
355 break;
356 case MLX5_CMD_OP_CREATE_CQ:
357 {
358 void *cqc;
359
360 MLX5_SET(create_cq_in, in, cq_umem_valid, 1);
361 cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
362 MLX5_SET(cqc, cqc, dbr_umem_valid, 1);
363 break;
364 }
365 case MLX5_CMD_OP_CREATE_QP:
366 {
367 void *qpc;
368
369 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
370 MLX5_SET(qpc, qpc, dbr_umem_valid, 1);
371 MLX5_SET(create_qp_in, in, wq_umem_valid, 1);
372 break;
373 }
374
375 case MLX5_CMD_OP_CREATE_RQ:
376 {
377 void *rqc, *wq;
378
379 rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
380 wq = MLX5_ADDR_OF(rqc, rqc, wq);
381 MLX5_SET(wq, wq, dbr_umem_valid, 1);
382 MLX5_SET(wq, wq, wq_umem_valid, 1);
383 break;
384 }
385
386 case MLX5_CMD_OP_CREATE_SQ:
387 {
388 void *sqc, *wq;
389
390 sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
391 wq = MLX5_ADDR_OF(sqc, sqc, wq);
392 MLX5_SET(wq, wq, dbr_umem_valid, 1);
393 MLX5_SET(wq, wq, wq_umem_valid, 1);
394 break;
395 }
396
397 case MLX5_CMD_OP_MODIFY_CQ:
398 MLX5_SET(modify_cq_in, in, cq_umem_valid, 1);
399 break;
400
401 case MLX5_CMD_OP_CREATE_RMP:
402 {
403 void *rmpc, *wq;
404
405 rmpc = MLX5_ADDR_OF(create_rmp_in, in, ctx);
406 wq = MLX5_ADDR_OF(rmpc, rmpc, wq);
407 MLX5_SET(wq, wq, dbr_umem_valid, 1);
408 MLX5_SET(wq, wq, wq_umem_valid, 1);
409 break;
410 }
411
412 case MLX5_CMD_OP_CREATE_XRQ:
413 {
414 void *xrqc, *wq;
415
416 xrqc = MLX5_ADDR_OF(create_xrq_in, in, xrq_context);
417 wq = MLX5_ADDR_OF(xrqc, xrqc, wq);
418 MLX5_SET(wq, wq, dbr_umem_valid, 1);
419 MLX5_SET(wq, wq, wq_umem_valid, 1);
420 break;
421 }
422
423 case MLX5_CMD_OP_CREATE_XRC_SRQ:
424 {
425 void *xrc_srqc;
426
427 MLX5_SET(create_xrc_srq_in, in, xrc_srq_umem_valid, 1);
428 xrc_srqc = MLX5_ADDR_OF(create_xrc_srq_in, in,
429 xrc_srq_context_entry);
430 MLX5_SET(xrc_srqc, xrc_srqc, dbr_umem_valid, 1);
431 break;
432 }
433
434 default:
435 return;
436 }
437}
438
Yishai Hadas2351776e2018-10-07 12:06:34 +0300439static bool devx_is_obj_create_cmd(const void *in, u16 *opcode)
Yishai Hadas7efce362018-06-17 13:00:01 +0300440{
Yishai Hadas2351776e2018-10-07 12:06:34 +0300441 *opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
Yishai Hadas7efce362018-06-17 13:00:01 +0300442
Yishai Hadas2351776e2018-10-07 12:06:34 +0300443 switch (*opcode) {
Yishai Hadas7efce362018-06-17 13:00:01 +0300444 case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
445 case MLX5_CMD_OP_CREATE_MKEY:
446 case MLX5_CMD_OP_CREATE_CQ:
447 case MLX5_CMD_OP_ALLOC_PD:
448 case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN:
449 case MLX5_CMD_OP_CREATE_RMP:
450 case MLX5_CMD_OP_CREATE_SQ:
451 case MLX5_CMD_OP_CREATE_RQ:
452 case MLX5_CMD_OP_CREATE_RQT:
453 case MLX5_CMD_OP_CREATE_TIR:
454 case MLX5_CMD_OP_CREATE_TIS:
455 case MLX5_CMD_OP_ALLOC_Q_COUNTER:
456 case MLX5_CMD_OP_CREATE_FLOW_TABLE:
457 case MLX5_CMD_OP_CREATE_FLOW_GROUP:
458 case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
Mark Bloch60786f02018-08-28 14:18:46 +0300459 case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT:
Yishai Hadas7efce362018-06-17 13:00:01 +0300460 case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
461 case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
462 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
463 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
464 case MLX5_CMD_OP_CREATE_QP:
465 case MLX5_CMD_OP_CREATE_SRQ:
466 case MLX5_CMD_OP_CREATE_XRC_SRQ:
467 case MLX5_CMD_OP_CREATE_DCT:
468 case MLX5_CMD_OP_CREATE_XRQ:
469 case MLX5_CMD_OP_ATTACH_TO_MCG:
470 case MLX5_CMD_OP_ALLOC_XRCD:
471 return true;
472 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
473 {
474 u16 op_mod = MLX5_GET(set_fte_in, in, op_mod);
475 if (op_mod == 0)
476 return true;
477 return false;
478 }
479 default:
480 return false;
481 }
482}
483
Yishai Hadase662e142018-06-17 13:00:02 +0300484static bool devx_is_obj_modify_cmd(const void *in)
485{
486 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
487
488 switch (opcode) {
489 case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
490 case MLX5_CMD_OP_MODIFY_CQ:
491 case MLX5_CMD_OP_MODIFY_RMP:
492 case MLX5_CMD_OP_MODIFY_SQ:
493 case MLX5_CMD_OP_MODIFY_RQ:
494 case MLX5_CMD_OP_MODIFY_RQT:
495 case MLX5_CMD_OP_MODIFY_TIR:
496 case MLX5_CMD_OP_MODIFY_TIS:
497 case MLX5_CMD_OP_MODIFY_FLOW_TABLE:
498 case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT:
499 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
500 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
501 case MLX5_CMD_OP_RST2INIT_QP:
502 case MLX5_CMD_OP_INIT2RTR_QP:
503 case MLX5_CMD_OP_RTR2RTS_QP:
504 case MLX5_CMD_OP_RTS2RTS_QP:
505 case MLX5_CMD_OP_SQERR2RTS_QP:
506 case MLX5_CMD_OP_2ERR_QP:
507 case MLX5_CMD_OP_2RST_QP:
508 case MLX5_CMD_OP_ARM_XRC_SRQ:
509 case MLX5_CMD_OP_ARM_RQ:
510 case MLX5_CMD_OP_DRAIN_DCT:
511 case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
512 case MLX5_CMD_OP_ARM_XRQ:
513 return true;
514 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
515 {
516 u16 op_mod = MLX5_GET(set_fte_in, in, op_mod);
517
518 if (op_mod == 1)
519 return true;
520 return false;
521 }
522 default:
523 return false;
524 }
525}
526
527static bool devx_is_obj_query_cmd(const void *in)
528{
529 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
530
531 switch (opcode) {
532 case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
533 case MLX5_CMD_OP_QUERY_MKEY:
534 case MLX5_CMD_OP_QUERY_CQ:
535 case MLX5_CMD_OP_QUERY_RMP:
536 case MLX5_CMD_OP_QUERY_SQ:
537 case MLX5_CMD_OP_QUERY_RQ:
538 case MLX5_CMD_OP_QUERY_RQT:
539 case MLX5_CMD_OP_QUERY_TIR:
540 case MLX5_CMD_OP_QUERY_TIS:
541 case MLX5_CMD_OP_QUERY_Q_COUNTER:
542 case MLX5_CMD_OP_QUERY_FLOW_TABLE:
543 case MLX5_CMD_OP_QUERY_FLOW_GROUP:
544 case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
545 case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
546 case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT:
547 case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
548 case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY:
549 case MLX5_CMD_OP_QUERY_QP:
550 case MLX5_CMD_OP_QUERY_SRQ:
551 case MLX5_CMD_OP_QUERY_XRC_SRQ:
552 case MLX5_CMD_OP_QUERY_DCT:
553 case MLX5_CMD_OP_QUERY_XRQ:
554 return true;
555 default:
556 return false;
557 }
558}
559
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300560static bool devx_is_whitelist_cmd(void *in)
561{
562 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
563
564 switch (opcode) {
565 case MLX5_CMD_OP_QUERY_HCA_CAP:
566 case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT:
567 return true;
568 default:
569 return false;
570 }
571}
572
573static int devx_get_uid(struct mlx5_ib_ucontext *c, void *cmd_in)
574{
575 if (devx_is_whitelist_cmd(cmd_in)) {
576 struct mlx5_ib_dev *dev;
577
578 if (c->devx_uid)
579 return c->devx_uid;
580
581 dev = to_mdev(c->ibucontext.device);
582 if (dev->devx_whitelist_uid)
583 return dev->devx_whitelist_uid;
584
585 return -EOPNOTSUPP;
586 }
587
588 if (!c->devx_uid)
589 return -EINVAL;
590
591 if (!capable(CAP_NET_RAW))
592 return -EPERM;
593
594 return c->devx_uid;
595}
Yishai Hadase662e142018-06-17 13:00:02 +0300596static bool devx_is_general_cmd(void *in)
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300597{
598 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
599
600 switch (opcode) {
601 case MLX5_CMD_OP_QUERY_HCA_CAP:
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300602 case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT:
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300603 case MLX5_CMD_OP_QUERY_VPORT_STATE:
604 case MLX5_CMD_OP_QUERY_ADAPTER:
605 case MLX5_CMD_OP_QUERY_ISSI:
606 case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT:
607 case MLX5_CMD_OP_QUERY_ROCE_ADDRESS:
608 case MLX5_CMD_OP_QUERY_VNIC_ENV:
609 case MLX5_CMD_OP_QUERY_VPORT_COUNTER:
610 case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG:
611 case MLX5_CMD_OP_NOP:
612 case MLX5_CMD_OP_QUERY_CONG_STATUS:
613 case MLX5_CMD_OP_QUERY_CONG_PARAMS:
614 case MLX5_CMD_OP_QUERY_CONG_STATISTICS:
615 return true;
616 default:
617 return false;
618 }
619}
620
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600621static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_EQN)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200622 struct uverbs_attr_bundle *attrs)
Yishai Hadasf6fe01b2018-06-17 13:00:05 +0300623{
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600624 struct mlx5_ib_ucontext *c;
625 struct mlx5_ib_dev *dev;
Yishai Hadasf6fe01b2018-06-17 13:00:05 +0300626 int user_vector;
627 int dev_eqn;
628 unsigned int irqn;
629 int err;
630
631 if (uverbs_copy_from(&user_vector, attrs,
632 MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC))
633 return -EFAULT;
634
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200635 c = devx_ufile2uctx(attrs);
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600636 if (IS_ERR(c))
637 return PTR_ERR(c);
638 dev = to_mdev(c->ibucontext.device);
639
Yishai Hadasf6fe01b2018-06-17 13:00:05 +0300640 err = mlx5_vector2eqn(dev->mdev, user_vector, &dev_eqn, &irqn);
641 if (err < 0)
642 return err;
643
644 if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN,
645 &dev_eqn, sizeof(dev_eqn)))
646 return -EFAULT;
647
648 return 0;
649}
650
Yishai Hadas7c043e92018-06-17 13:00:03 +0300651/*
652 *Security note:
653 * The hardware protection mechanism works like this: Each device object that
654 * is subject to UAR doorbells (QP/SQ/CQ) gets a UAR ID (called uar_page in
655 * the device specification manual) upon its creation. Then upon doorbell,
656 * hardware fetches the object context for which the doorbell was rang, and
657 * validates that the UAR through which the DB was rang matches the UAR ID
658 * of the object.
659 * If no match the doorbell is silently ignored by the hardware. Of course,
660 * the user cannot ring a doorbell on a UAR that was not mapped to it.
661 * Now in devx, as the devx kernel does not manipulate the QP/SQ/CQ command
662 * mailboxes (except tagging them with UID), we expose to the user its UAR
663 * ID, so it can embed it in these objects in the expected specification
664 * format. So the only thing the user can do is hurt itself by creating a
665 * QP/SQ/CQ with a UAR ID other than his, and then in this case other users
666 * may ring a doorbell on its objects.
667 * The consequence of that will be that another user can schedule a QP/SQ
668 * of the buggy user for execution (just insert it to the hardware schedule
669 * queue or arm its CQ for event generation), no further harm is expected.
670 */
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600671static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_UAR)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200672 struct uverbs_attr_bundle *attrs)
Yishai Hadas7c043e92018-06-17 13:00:03 +0300673{
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600674 struct mlx5_ib_ucontext *c;
675 struct mlx5_ib_dev *dev;
Yishai Hadas7c043e92018-06-17 13:00:03 +0300676 u32 user_idx;
677 s32 dev_idx;
678
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200679 c = devx_ufile2uctx(attrs);
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600680 if (IS_ERR(c))
681 return PTR_ERR(c);
682 dev = to_mdev(c->ibucontext.device);
683
Yishai Hadas7c043e92018-06-17 13:00:03 +0300684 if (uverbs_copy_from(&user_idx, attrs,
685 MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX))
686 return -EFAULT;
687
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600688 dev_idx = bfregn_to_uar_index(dev, &c->bfregi, user_idx, true);
Yishai Hadas7c043e92018-06-17 13:00:03 +0300689 if (dev_idx < 0)
690 return dev_idx;
691
692 if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX,
693 &dev_idx, sizeof(dev_idx)))
694 return -EFAULT;
695
696 return 0;
697}
698
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600699static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200700 struct uverbs_attr_bundle *attrs)
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300701{
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600702 struct mlx5_ib_ucontext *c;
703 struct mlx5_ib_dev *dev;
Yishai Hadas7efce362018-06-17 13:00:01 +0300704 void *cmd_in = uverbs_attr_get_alloced_ptr(
705 attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300706 int cmd_out_len = uverbs_attr_get_len(attrs,
707 MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT);
708 void *cmd_out;
709 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300710 int uid;
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300711
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200712 c = devx_ufile2uctx(attrs);
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600713 if (IS_ERR(c))
714 return PTR_ERR(c);
715 dev = to_mdev(c->ibucontext.device);
716
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300717 uid = devx_get_uid(c, cmd_in);
718 if (uid < 0)
719 return uid;
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300720
721 /* Only white list of some general HCA commands are allowed for this method. */
722 if (!devx_is_general_cmd(cmd_in))
723 return -EINVAL;
724
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600725 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
726 if (IS_ERR(cmd_out))
727 return PTR_ERR(cmd_out);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300728
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300729 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300730 err = mlx5_cmd_exec(dev->mdev, cmd_in,
731 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN),
732 cmd_out, cmd_out_len);
733 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600734 return err;
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300735
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600736 return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out,
737 cmd_out_len);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300738}
739
Yishai Hadas7efce362018-06-17 13:00:01 +0300740static void devx_obj_build_destroy_cmd(void *in, void *out, void *din,
741 u32 *dinlen,
742 u32 *obj_id)
743{
744 u16 obj_type = MLX5_GET(general_obj_in_cmd_hdr, in, obj_type);
745 u16 uid = MLX5_GET(general_obj_in_cmd_hdr, in, uid);
746
747 *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
748 *dinlen = MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr);
749
750 MLX5_SET(general_obj_in_cmd_hdr, din, obj_id, *obj_id);
751 MLX5_SET(general_obj_in_cmd_hdr, din, uid, uid);
752
753 switch (MLX5_GET(general_obj_in_cmd_hdr, in, opcode)) {
754 case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
755 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
756 MLX5_SET(general_obj_in_cmd_hdr, din, obj_type, obj_type);
757 break;
758
759 case MLX5_CMD_OP_CREATE_MKEY:
760 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_MKEY);
761 break;
762 case MLX5_CMD_OP_CREATE_CQ:
763 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_CQ);
764 break;
765 case MLX5_CMD_OP_ALLOC_PD:
766 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_PD);
767 break;
768 case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN:
769 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
770 MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN);
771 break;
772 case MLX5_CMD_OP_CREATE_RMP:
773 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RMP);
774 break;
775 case MLX5_CMD_OP_CREATE_SQ:
776 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SQ);
777 break;
778 case MLX5_CMD_OP_CREATE_RQ:
779 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQ);
780 break;
781 case MLX5_CMD_OP_CREATE_RQT:
782 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT);
783 break;
784 case MLX5_CMD_OP_CREATE_TIR:
785 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIR);
786 break;
787 case MLX5_CMD_OP_CREATE_TIS:
788 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS);
789 break;
790 case MLX5_CMD_OP_ALLOC_Q_COUNTER:
791 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
792 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
793 break;
794 case MLX5_CMD_OP_CREATE_FLOW_TABLE:
795 *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_table_in);
796 *obj_id = MLX5_GET(create_flow_table_out, out, table_id);
797 MLX5_SET(destroy_flow_table_in, din, other_vport,
798 MLX5_GET(create_flow_table_in, in, other_vport));
799 MLX5_SET(destroy_flow_table_in, din, vport_number,
800 MLX5_GET(create_flow_table_in, in, vport_number));
801 MLX5_SET(destroy_flow_table_in, din, table_type,
802 MLX5_GET(create_flow_table_in, in, table_type));
803 MLX5_SET(destroy_flow_table_in, din, table_id, *obj_id);
804 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
805 MLX5_CMD_OP_DESTROY_FLOW_TABLE);
806 break;
807 case MLX5_CMD_OP_CREATE_FLOW_GROUP:
808 *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_group_in);
809 *obj_id = MLX5_GET(create_flow_group_out, out, group_id);
810 MLX5_SET(destroy_flow_group_in, din, other_vport,
811 MLX5_GET(create_flow_group_in, in, other_vport));
812 MLX5_SET(destroy_flow_group_in, din, vport_number,
813 MLX5_GET(create_flow_group_in, in, vport_number));
814 MLX5_SET(destroy_flow_group_in, din, table_type,
815 MLX5_GET(create_flow_group_in, in, table_type));
816 MLX5_SET(destroy_flow_group_in, din, table_id,
817 MLX5_GET(create_flow_group_in, in, table_id));
818 MLX5_SET(destroy_flow_group_in, din, group_id, *obj_id);
819 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
820 MLX5_CMD_OP_DESTROY_FLOW_GROUP);
821 break;
822 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
823 *dinlen = MLX5_ST_SZ_BYTES(delete_fte_in);
824 *obj_id = MLX5_GET(set_fte_in, in, flow_index);
825 MLX5_SET(delete_fte_in, din, other_vport,
826 MLX5_GET(set_fte_in, in, other_vport));
827 MLX5_SET(delete_fte_in, din, vport_number,
828 MLX5_GET(set_fte_in, in, vport_number));
829 MLX5_SET(delete_fte_in, din, table_type,
830 MLX5_GET(set_fte_in, in, table_type));
831 MLX5_SET(delete_fte_in, din, table_id,
832 MLX5_GET(set_fte_in, in, table_id));
833 MLX5_SET(delete_fte_in, din, flow_index, *obj_id);
834 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
835 MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
836 break;
837 case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
838 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
839 MLX5_CMD_OP_DEALLOC_FLOW_COUNTER);
840 break;
Mark Bloch60786f02018-08-28 14:18:46 +0300841 case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT:
Yishai Hadas7efce362018-06-17 13:00:01 +0300842 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
Mark Bloch60786f02018-08-28 14:18:46 +0300843 MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
Yishai Hadas7efce362018-06-17 13:00:01 +0300844 break;
845 case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
846 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
847 MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
848 break;
849 case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
850 *dinlen = MLX5_ST_SZ_BYTES(destroy_scheduling_element_in);
851 *obj_id = MLX5_GET(create_scheduling_element_out, out,
852 scheduling_element_id);
853 MLX5_SET(destroy_scheduling_element_in, din,
854 scheduling_hierarchy,
855 MLX5_GET(create_scheduling_element_in, in,
856 scheduling_hierarchy));
857 MLX5_SET(destroy_scheduling_element_in, din,
858 scheduling_element_id, *obj_id);
859 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
860 MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT);
861 break;
862 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
863 *dinlen = MLX5_ST_SZ_BYTES(delete_vxlan_udp_dport_in);
864 *obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port);
865 MLX5_SET(delete_vxlan_udp_dport_in, din, vxlan_udp_port, *obj_id);
866 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
867 MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
868 break;
869 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
870 *dinlen = MLX5_ST_SZ_BYTES(delete_l2_table_entry_in);
871 *obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index);
872 MLX5_SET(delete_l2_table_entry_in, din, table_index, *obj_id);
873 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
874 MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY);
875 break;
876 case MLX5_CMD_OP_CREATE_QP:
877 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_QP);
878 break;
879 case MLX5_CMD_OP_CREATE_SRQ:
880 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SRQ);
881 break;
882 case MLX5_CMD_OP_CREATE_XRC_SRQ:
883 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
884 MLX5_CMD_OP_DESTROY_XRC_SRQ);
885 break;
886 case MLX5_CMD_OP_CREATE_DCT:
887 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_DCT);
888 break;
889 case MLX5_CMD_OP_CREATE_XRQ:
890 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_XRQ);
891 break;
892 case MLX5_CMD_OP_ATTACH_TO_MCG:
893 *dinlen = MLX5_ST_SZ_BYTES(detach_from_mcg_in);
894 MLX5_SET(detach_from_mcg_in, din, qpn,
895 MLX5_GET(attach_to_mcg_in, in, qpn));
896 memcpy(MLX5_ADDR_OF(detach_from_mcg_in, din, multicast_gid),
897 MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid),
898 MLX5_FLD_SZ_BYTES(attach_to_mcg_in, multicast_gid));
899 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DETACH_FROM_MCG);
900 break;
901 case MLX5_CMD_OP_ALLOC_XRCD:
902 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
903 break;
904 default:
905 /* The entry must match to one of the devx_is_obj_create_cmd */
906 WARN_ON(true);
907 break;
908 }
909}
910
911static int devx_obj_cleanup(struct ib_uobject *uobject,
912 enum rdma_remove_reason why)
913{
914 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
915 struct devx_obj *obj = uobject->object;
916 int ret;
917
918 ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
Yishai Hadas1c774832018-06-20 17:11:39 +0300919 if (ib_is_destroy_retryable(ret, why, uobject))
Yishai Hadas7efce362018-06-17 13:00:01 +0300920 return ret;
921
922 kfree(obj);
923 return ret;
924}
925
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600926static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200927 struct uverbs_attr_bundle *attrs)
Yishai Hadas7efce362018-06-17 13:00:01 +0300928{
Yishai Hadas7efce362018-06-17 13:00:01 +0300929 void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN);
930 int cmd_out_len = uverbs_attr_get_len(attrs,
931 MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT);
932 void *cmd_out;
Jason Gunthorpec36ee462018-07-10 20:55:22 -0600933 struct ib_uobject *uobj = uverbs_attr_get_uobject(
934 attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE);
935 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
936 struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device);
Yishai Hadase8ef0902018-09-25 12:11:12 +0300937 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
Yishai Hadas7efce362018-06-17 13:00:01 +0300938 struct devx_obj *obj;
939 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300940 int uid;
Yishai Hadas2351776e2018-10-07 12:06:34 +0300941 u32 obj_id;
942 u16 opcode;
Yishai Hadas7efce362018-06-17 13:00:01 +0300943
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300944 uid = devx_get_uid(c, cmd_in);
945 if (uid < 0)
946 return uid;
Yishai Hadas7efce362018-06-17 13:00:01 +0300947
Yishai Hadas2351776e2018-10-07 12:06:34 +0300948 if (!devx_is_obj_create_cmd(cmd_in, &opcode))
Yishai Hadas7efce362018-06-17 13:00:01 +0300949 return -EINVAL;
950
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600951 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
952 if (IS_ERR(cmd_out))
953 return PTR_ERR(cmd_out);
954
Yishai Hadas7efce362018-06-17 13:00:01 +0300955 obj = kzalloc(sizeof(struct devx_obj), GFP_KERNEL);
956 if (!obj)
957 return -ENOMEM;
958
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300959 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Yishai Hadasba1a0572018-09-20 21:39:33 +0300960 devx_set_umem_valid(cmd_in);
961
Yishai Hadas7efce362018-06-17 13:00:01 +0300962 err = mlx5_cmd_exec(dev->mdev, cmd_in,
963 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN),
964 cmd_out, cmd_out_len);
965 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600966 goto obj_free;
Yishai Hadas7efce362018-06-17 13:00:01 +0300967
Yishai Hadas7efce362018-06-17 13:00:01 +0300968 uobj->object = obj;
969 obj->mdev = dev->mdev;
Yishai Hadas2351776e2018-10-07 12:06:34 +0300970 devx_obj_build_destroy_cmd(cmd_in, cmd_out, obj->dinbox, &obj->dinlen,
971 &obj_id);
Yishai Hadas7efce362018-06-17 13:00:01 +0300972 WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32));
973
974 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len);
975 if (err)
Yishai Hadase8ef0902018-09-25 12:11:12 +0300976 goto obj_destroy;
Yishai Hadas7efce362018-06-17 13:00:01 +0300977
Yishai Hadas2351776e2018-10-07 12:06:34 +0300978 obj->obj_id = get_enc_obj_id(opcode, obj_id);
Yishai Hadas7efce362018-06-17 13:00:01 +0300979 return 0;
980
Yishai Hadase8ef0902018-09-25 12:11:12 +0300981obj_destroy:
982 mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
Yishai Hadas7efce362018-06-17 13:00:01 +0300983obj_free:
984 kfree(obj);
985 return err;
986}
987
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600988static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MODIFY)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200989 struct uverbs_attr_bundle *attrs)
Yishai Hadase662e142018-06-17 13:00:02 +0300990{
Yishai Hadase662e142018-06-17 13:00:02 +0300991 void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN);
992 int cmd_out_len = uverbs_attr_get_len(attrs,
993 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT);
994 struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
995 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE);
Jason Gunthorpec36ee462018-07-10 20:55:22 -0600996 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
997 struct devx_obj *obj = uobj->object;
Yishai Hadase662e142018-06-17 13:00:02 +0300998 void *cmd_out;
999 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001000 int uid;
Yishai Hadase662e142018-06-17 13:00:02 +03001001
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001002 uid = devx_get_uid(c, cmd_in);
1003 if (uid < 0)
1004 return uid;
Yishai Hadase662e142018-06-17 13:00:02 +03001005
1006 if (!devx_is_obj_modify_cmd(cmd_in))
1007 return -EINVAL;
1008
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001009 if (!devx_is_valid_obj_id(obj, cmd_in))
Yishai Hadase662e142018-06-17 13:00:02 +03001010 return -EINVAL;
1011
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001012 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
1013 if (IS_ERR(cmd_out))
1014 return PTR_ERR(cmd_out);
Yishai Hadase662e142018-06-17 13:00:02 +03001015
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001016 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Yishai Hadasba1a0572018-09-20 21:39:33 +03001017 devx_set_umem_valid(cmd_in);
1018
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001019 err = mlx5_cmd_exec(obj->mdev, cmd_in,
Yishai Hadase662e142018-06-17 13:00:02 +03001020 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN),
1021 cmd_out, cmd_out_len);
1022 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001023 return err;
Yishai Hadase662e142018-06-17 13:00:02 +03001024
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001025 return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
1026 cmd_out, cmd_out_len);
Yishai Hadase662e142018-06-17 13:00:02 +03001027}
1028
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -06001029static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +02001030 struct uverbs_attr_bundle *attrs)
Yishai Hadase662e142018-06-17 13:00:02 +03001031{
Yishai Hadase662e142018-06-17 13:00:02 +03001032 void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN);
1033 int cmd_out_len = uverbs_attr_get_len(attrs,
1034 MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT);
1035 struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
1036 MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE);
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001037 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
1038 struct devx_obj *obj = uobj->object;
Yishai Hadase662e142018-06-17 13:00:02 +03001039 void *cmd_out;
1040 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001041 int uid;
Yishai Hadase662e142018-06-17 13:00:02 +03001042
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001043 uid = devx_get_uid(c, cmd_in);
1044 if (uid < 0)
1045 return uid;
Yishai Hadase662e142018-06-17 13:00:02 +03001046
1047 if (!devx_is_obj_query_cmd(cmd_in))
1048 return -EINVAL;
1049
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001050 if (!devx_is_valid_obj_id(obj, cmd_in))
Yishai Hadase662e142018-06-17 13:00:02 +03001051 return -EINVAL;
1052
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001053 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
1054 if (IS_ERR(cmd_out))
1055 return PTR_ERR(cmd_out);
Yishai Hadase662e142018-06-17 13:00:02 +03001056
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001057 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001058 err = mlx5_cmd_exec(obj->mdev, cmd_in,
Yishai Hadase662e142018-06-17 13:00:02 +03001059 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN),
1060 cmd_out, cmd_out_len);
1061 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001062 return err;
Yishai Hadase662e142018-06-17 13:00:02 +03001063
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001064 return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
1065 cmd_out, cmd_out_len);
Yishai Hadase662e142018-06-17 13:00:02 +03001066}
1067
Yishai Hadasaeae9452018-06-17 13:00:04 +03001068static int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext,
1069 struct uverbs_attr_bundle *attrs,
1070 struct devx_umem *obj)
1071{
1072 u64 addr;
1073 size_t size;
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001074 u32 access;
Yishai Hadasaeae9452018-06-17 13:00:04 +03001075 int npages;
1076 int err;
1077 u32 page_mask;
1078
1079 if (uverbs_copy_from(&addr, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR) ||
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001080 uverbs_copy_from(&size, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_LEN))
Yishai Hadasaeae9452018-06-17 13:00:04 +03001081 return -EFAULT;
1082
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001083 err = uverbs_get_flags32(&access, attrs,
1084 MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS,
1085 IB_ACCESS_SUPPORTED);
1086 if (err)
1087 return err;
1088
Yishai Hadasaeae9452018-06-17 13:00:04 +03001089 err = ib_check_mr_access(access);
1090 if (err)
1091 return err;
1092
1093 obj->umem = ib_umem_get(ucontext, addr, size, access, 0);
1094 if (IS_ERR(obj->umem))
1095 return PTR_ERR(obj->umem);
1096
1097 mlx5_ib_cont_pages(obj->umem, obj->umem->address,
1098 MLX5_MKEY_PAGE_SHIFT_MASK, &npages,
1099 &obj->page_shift, &obj->ncont, NULL);
1100
1101 if (!npages) {
1102 ib_umem_release(obj->umem);
1103 return -EINVAL;
1104 }
1105
1106 page_mask = (1 << obj->page_shift) - 1;
1107 obj->page_offset = obj->umem->address & page_mask;
1108
1109 return 0;
1110}
1111
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001112static int devx_umem_reg_cmd_alloc(struct uverbs_attr_bundle *attrs,
1113 struct devx_umem *obj,
Yishai Hadasaeae9452018-06-17 13:00:04 +03001114 struct devx_umem_reg_cmd *cmd)
1115{
1116 cmd->inlen = MLX5_ST_SZ_BYTES(create_umem_in) +
1117 (MLX5_ST_SZ_BYTES(mtt) * obj->ncont);
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001118 cmd->in = uverbs_zalloc(attrs, cmd->inlen);
1119 return PTR_ERR_OR_ZERO(cmd->in);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001120}
1121
1122static void devx_umem_reg_cmd_build(struct mlx5_ib_dev *dev,
1123 struct devx_umem *obj,
1124 struct devx_umem_reg_cmd *cmd)
1125{
1126 void *umem;
1127 __be64 *mtt;
1128
1129 umem = MLX5_ADDR_OF(create_umem_in, cmd->in, umem);
1130 mtt = (__be64 *)MLX5_ADDR_OF(umem, umem, mtt);
1131
1132 MLX5_SET(general_obj_in_cmd_hdr, cmd->in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
1133 MLX5_SET(general_obj_in_cmd_hdr, cmd->in, obj_type, MLX5_OBJ_TYPE_UMEM);
1134 MLX5_SET64(umem, umem, num_of_mtt, obj->ncont);
1135 MLX5_SET(umem, umem, log_page_size, obj->page_shift -
1136 MLX5_ADAPTER_PAGE_SHIFT);
1137 MLX5_SET(umem, umem, page_offset, obj->page_offset);
1138 mlx5_ib_populate_pas(dev, obj->umem, obj->page_shift, mtt,
1139 (obj->umem->writable ? MLX5_IB_MTT_WRITE : 0) |
1140 MLX5_IB_MTT_READ);
1141}
1142
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -06001143static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_REG)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +02001144 struct uverbs_attr_bundle *attrs)
Yishai Hadasaeae9452018-06-17 13:00:04 +03001145{
Yishai Hadasaeae9452018-06-17 13:00:04 +03001146 struct devx_umem_reg_cmd cmd;
1147 struct devx_umem *obj;
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001148 struct ib_uobject *uobj = uverbs_attr_get_uobject(
1149 attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001150 u32 obj_id;
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001151 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
1152 struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001153 int err;
1154
1155 if (!c->devx_uid)
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001156 return -EINVAL;
1157
1158 if (!capable(CAP_NET_RAW))
Yishai Hadasaeae9452018-06-17 13:00:04 +03001159 return -EPERM;
1160
Yishai Hadasaeae9452018-06-17 13:00:04 +03001161 obj = kzalloc(sizeof(struct devx_umem), GFP_KERNEL);
1162 if (!obj)
1163 return -ENOMEM;
1164
1165 err = devx_umem_get(dev, &c->ibucontext, attrs, obj);
1166 if (err)
1167 goto err_obj_free;
1168
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001169 err = devx_umem_reg_cmd_alloc(attrs, obj, &cmd);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001170 if (err)
1171 goto err_umem_release;
1172
1173 devx_umem_reg_cmd_build(dev, obj, &cmd);
1174
1175 MLX5_SET(general_obj_in_cmd_hdr, cmd.in, uid, c->devx_uid);
1176 err = mlx5_cmd_exec(dev->mdev, cmd.in, cmd.inlen, cmd.out,
1177 sizeof(cmd.out));
1178 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001179 goto err_umem_release;
Yishai Hadasaeae9452018-06-17 13:00:04 +03001180
1181 obj->mdev = dev->mdev;
1182 uobj->object = obj;
1183 devx_obj_build_destroy_cmd(cmd.in, cmd.out, obj->dinbox, &obj->dinlen, &obj_id);
1184 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, &obj_id, sizeof(obj_id));
1185 if (err)
1186 goto err_umem_destroy;
1187
Yishai Hadasaeae9452018-06-17 13:00:04 +03001188 return 0;
1189
1190err_umem_destroy:
1191 mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, cmd.out, sizeof(cmd.out));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001192err_umem_release:
1193 ib_umem_release(obj->umem);
1194err_obj_free:
1195 kfree(obj);
1196 return err;
1197}
1198
Yishai Hadasaeae9452018-06-17 13:00:04 +03001199static int devx_umem_cleanup(struct ib_uobject *uobject,
1200 enum rdma_remove_reason why)
1201{
1202 struct devx_umem *obj = uobject->object;
1203 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
1204 int err;
1205
1206 err = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
Yishai Hadas1c774832018-06-20 17:11:39 +03001207 if (ib_is_destroy_retryable(err, why, uobject))
Yishai Hadasaeae9452018-06-17 13:00:04 +03001208 return err;
1209
1210 ib_umem_release(obj->umem);
1211 kfree(obj);
1212 return 0;
1213}
1214
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001215DECLARE_UVERBS_NAMED_METHOD(
1216 MLX5_IB_METHOD_DEVX_UMEM_REG,
1217 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE,
1218 MLX5_IB_OBJECT_DEVX_UMEM,
1219 UVERBS_ACCESS_NEW,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001220 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001221 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR,
1222 UVERBS_ATTR_TYPE(u64),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001223 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001224 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_LEN,
1225 UVERBS_ATTR_TYPE(u64),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001226 UA_MANDATORY),
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001227 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS,
1228 enum ib_access_flags),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001229 UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID,
1230 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001231 UA_MANDATORY));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001232
Yishai Hadas528922a2018-07-08 13:24:39 +03001233DECLARE_UVERBS_NAMED_METHOD_DESTROY(
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001234 MLX5_IB_METHOD_DEVX_UMEM_DEREG,
1235 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE,
1236 MLX5_IB_OBJECT_DEVX_UMEM,
1237 UVERBS_ACCESS_DESTROY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001238 UA_MANDATORY));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001239
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001240DECLARE_UVERBS_NAMED_METHOD(
1241 MLX5_IB_METHOD_DEVX_QUERY_EQN,
1242 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC,
1243 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001244 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001245 UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN,
1246 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001247 UA_MANDATORY));
Yishai Hadasf6fe01b2018-06-17 13:00:05 +03001248
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001249DECLARE_UVERBS_NAMED_METHOD(
1250 MLX5_IB_METHOD_DEVX_QUERY_UAR,
1251 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX,
1252 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001253 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001254 UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX,
1255 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001256 UA_MANDATORY));
Yishai Hadas7c043e92018-06-17 13:00:03 +03001257
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001258DECLARE_UVERBS_NAMED_METHOD(
1259 MLX5_IB_METHOD_DEVX_OTHER,
1260 UVERBS_ATTR_PTR_IN(
1261 MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
1262 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001263 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001264 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001265 UVERBS_ATTR_PTR_OUT(
1266 MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT,
1267 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001268 UA_MANDATORY));
Yishai Hadas8aa8c952018-06-17 13:00:00 +03001269
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001270DECLARE_UVERBS_NAMED_METHOD(
1271 MLX5_IB_METHOD_DEVX_OBJ_CREATE,
1272 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE,
1273 MLX5_IB_OBJECT_DEVX_OBJ,
1274 UVERBS_ACCESS_NEW,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001275 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001276 UVERBS_ATTR_PTR_IN(
1277 MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN,
1278 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001279 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001280 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001281 UVERBS_ATTR_PTR_OUT(
1282 MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT,
1283 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001284 UA_MANDATORY));
Yishai Hadas7efce362018-06-17 13:00:01 +03001285
Yishai Hadas528922a2018-07-08 13:24:39 +03001286DECLARE_UVERBS_NAMED_METHOD_DESTROY(
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001287 MLX5_IB_METHOD_DEVX_OBJ_DESTROY,
1288 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE,
1289 MLX5_IB_OBJECT_DEVX_OBJ,
1290 UVERBS_ACCESS_DESTROY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001291 UA_MANDATORY));
Yishai Hadas7efce362018-06-17 13:00:01 +03001292
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001293DECLARE_UVERBS_NAMED_METHOD(
1294 MLX5_IB_METHOD_DEVX_OBJ_MODIFY,
1295 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE,
1296 MLX5_IB_OBJECT_DEVX_OBJ,
1297 UVERBS_ACCESS_WRITE,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001298 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001299 UVERBS_ATTR_PTR_IN(
1300 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN,
1301 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001302 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001303 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001304 UVERBS_ATTR_PTR_OUT(
1305 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
1306 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001307 UA_MANDATORY));
Yishai Hadase662e142018-06-17 13:00:02 +03001308
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001309DECLARE_UVERBS_NAMED_METHOD(
1310 MLX5_IB_METHOD_DEVX_OBJ_QUERY,
1311 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE,
1312 MLX5_IB_OBJECT_DEVX_OBJ,
1313 UVERBS_ACCESS_READ,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001314 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001315 UVERBS_ATTR_PTR_IN(
1316 MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN,
1317 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001318 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001319 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001320 UVERBS_ATTR_PTR_OUT(
1321 MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
1322 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001323 UA_MANDATORY));
Yishai Hadase662e142018-06-17 13:00:02 +03001324
Jason Gunthorpe6c61d2a2018-07-04 08:50:27 +03001325DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001326 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER),
1327 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR),
1328 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_EQN));
Yishai Hadas8aa8c952018-06-17 13:00:00 +03001329
Jason Gunthorpe6c61d2a2018-07-04 08:50:27 +03001330DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001331 UVERBS_TYPE_ALLOC_IDR(devx_obj_cleanup),
1332 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE),
1333 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY),
1334 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY),
1335 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY));
Yishai Hadas7efce362018-06-17 13:00:01 +03001336
Jason Gunthorpe6c61d2a2018-07-04 08:50:27 +03001337DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001338 UVERBS_TYPE_ALLOC_IDR(devx_umem_cleanup),
1339 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG),
1340 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001341
Jason Gunthorpe36e235c2018-11-12 22:59:53 +02001342static bool devx_is_supported(struct ib_device *device)
1343{
1344 struct mlx5_ib_dev *dev = to_mdev(device);
1345
1346 return !dev->rep && MLX5_CAP_GEN_64(dev->mdev, general_obj_types) &
1347 MLX5_GENERAL_OBJ_TYPES_CAP_UCTX;
1348}
1349
Jason Gunthorpe0cbf4322018-11-12 22:59:50 +02001350const struct uapi_definition mlx5_ib_devx_defs[] = {
Jason Gunthorpe36e235c2018-11-12 22:59:53 +02001351 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
1352 MLX5_IB_OBJECT_DEVX,
1353 UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)),
1354 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
1355 MLX5_IB_OBJECT_DEVX_OBJ,
1356 UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)),
1357 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
1358 MLX5_IB_OBJECT_DEVX_UMEM,
1359 UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)),
Jason Gunthorpe0cbf4322018-11-12 22:59:50 +02001360 {},
1361};