blob: 9ca116155f9c82b0e84b0979e2826d9ccff55723 [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>
Yishai Hadasa124edb2019-01-22 08:29:57 +020011#include <rdma/mlx5_user_ioctl_verbs.h>
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030012#include <rdma/ib_umem.h>
Yishai Hadas34613eb2018-11-26 08:28:35 +020013#include <rdma/uverbs_std_types.h>
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030014#include <linux/mlx5/driver.h>
15#include <linux/mlx5/fs.h>
16#include "mlx5_ib.h"
17
Yishai Hadas8aa8c952018-06-17 13:00:00 +030018#define UVERBS_MODULE_NAME mlx5_ib
19#include <rdma/uverbs_named_ioctl.h>
20
Yishai Hadasa124edb2019-01-22 08:29:57 +020021struct devx_async_data {
22 struct mlx5_ib_dev *mdev;
23 struct list_head list;
24 struct ib_uobject *fd_uobj;
25 struct mlx5_async_work cb_work;
26 u16 cmd_out_len;
27 /* must be last field in this structure */
28 struct mlx5_ib_uapi_devx_async_cmd_hdr hdr;
29};
30
Yishai Hadas7efce362018-06-17 13:00:01 +030031#define MLX5_MAX_DESTROY_INBOX_SIZE_DW MLX5_ST_SZ_DW(delete_fte_in)
32struct devx_obj {
33 struct mlx5_core_dev *mdev;
Yishai Hadas2351776e2018-10-07 12:06:34 +030034 u64 obj_id;
Yishai Hadas7efce362018-06-17 13:00:01 +030035 u32 dinlen; /* destroy inbox length */
36 u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
37};
38
Yishai Hadasaeae9452018-06-17 13:00:04 +030039struct devx_umem {
40 struct mlx5_core_dev *mdev;
41 struct ib_umem *umem;
42 u32 page_offset;
43 int page_shift;
44 int ncont;
45 u32 dinlen;
46 u32 dinbox[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)];
47};
48
49struct devx_umem_reg_cmd {
50 void *in;
51 u32 inlen;
52 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
53};
54
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +020055static struct mlx5_ib_ucontext *
56devx_ufile2uctx(const struct uverbs_attr_bundle *attrs)
Yishai Hadas8aa8c952018-06-17 13:00:00 +030057{
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +020058 return to_mucontext(ib_uverbs_get_ucontext(attrs));
Yishai Hadas8aa8c952018-06-17 13:00:00 +030059}
60
Yishai Hadasfb981532018-11-26 08:28:36 +020061int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user)
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030062{
63 u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0};
64 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
Yishai Hadas6e3722b2018-12-19 16:28:15 +020065 void *uctx;
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030066 int err;
Yishai Hadas76dc5a82018-09-20 21:45:19 +030067 u16 uid;
Yishai Hadasfb981532018-11-26 08:28:36 +020068 u32 cap = 0;
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030069
Yishai Hadas6e3722b2018-12-19 16:28:15 +020070 /* 0 means not supported */
71 if (!MLX5_CAP_GEN(dev->mdev, log_max_uctx))
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030072 return -EINVAL;
73
Yishai Hadas6e3722b2018-12-19 16:28:15 +020074 uctx = MLX5_ADDR_OF(create_uctx_in, in, uctx);
Yishai Hadasfb981532018-11-26 08:28:36 +020075 if (is_user && capable(CAP_NET_RAW) &&
76 (MLX5_CAP_GEN(dev->mdev, uctx_cap) & MLX5_UCTX_CAP_RAW_TX))
77 cap |= MLX5_UCTX_CAP_RAW_TX;
78
Yishai Hadas6e3722b2018-12-19 16:28:15 +020079 MLX5_SET(create_uctx_in, in, opcode, MLX5_CMD_OP_CREATE_UCTX);
Yishai Hadasfb981532018-11-26 08:28:36 +020080 MLX5_SET(uctx, uctx, cap, cap);
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030081
82 err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
83 if (err)
84 return err;
85
Yishai Hadas76dc5a82018-09-20 21:45:19 +030086 uid = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
87 return uid;
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030088}
89
Yishai Hadas76dc5a82018-09-20 21:45:19 +030090void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid)
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030091{
Yishai Hadas6e3722b2018-12-19 16:28:15 +020092 u32 in[MLX5_ST_SZ_DW(destroy_uctx_in)] = {0};
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030093 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
94
Yishai Hadas6e3722b2018-12-19 16:28:15 +020095 MLX5_SET(destroy_uctx_in, in, opcode, MLX5_CMD_OP_DESTROY_UCTX);
96 MLX5_SET(destroy_uctx_in, in, uid, uid);
Yishai Hadasa8b92ca2018-06-17 12:59:57 +030097
98 mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
99}
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300100
Yishai Hadas32269442018-07-23 15:25:09 +0300101bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type)
102{
103 struct devx_obj *devx_obj = obj;
104 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
105
106 switch (opcode) {
107 case MLX5_CMD_OP_DESTROY_TIR:
108 *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR;
109 *dest_id = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox,
110 obj_id);
111 return true;
112
113 case MLX5_CMD_OP_DESTROY_FLOW_TABLE:
114 *dest_type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
115 *dest_id = MLX5_GET(destroy_flow_table_in, devx_obj->dinbox,
116 table_id);
117 return true;
118 default:
119 return false;
120 }
121}
122
Mark Blochbfc5d832018-11-20 20:31:08 +0200123bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id)
124{
125 struct devx_obj *devx_obj = obj;
126 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
127
128 if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) {
129 *counter_id = MLX5_GET(dealloc_flow_counter_in,
130 devx_obj->dinbox,
131 flow_counter_id);
132 return true;
133 }
134
135 return false;
136}
137
Yishai Hadas2351776e2018-10-07 12:06:34 +0300138/*
139 * As the obj_id in the firmware is not globally unique the object type
140 * must be considered upon checking for a valid object id.
141 * For that the opcode of the creator command is encoded as part of the obj_id.
142 */
143static u64 get_enc_obj_id(u16 opcode, u32 obj_id)
144{
145 return ((u64)opcode << 32) | obj_id;
146}
147
Yishai Hadas34613eb2018-11-26 08:28:35 +0200148static u64 devx_get_obj_id(const void *in)
Yishai Hadase662e142018-06-17 13:00:02 +0300149{
150 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
Yishai Hadas2351776e2018-10-07 12:06:34 +0300151 u64 obj_id;
Yishai Hadase662e142018-06-17 13:00:02 +0300152
153 switch (opcode) {
154 case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
155 case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300156 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_GENERAL_OBJECT,
157 MLX5_GET(general_obj_in_cmd_hdr, in,
158 obj_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300159 break;
160 case MLX5_CMD_OP_QUERY_MKEY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300161 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_MKEY,
162 MLX5_GET(query_mkey_in, in,
163 mkey_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300164 break;
165 case MLX5_CMD_OP_QUERY_CQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300166 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ,
167 MLX5_GET(query_cq_in, in, cqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300168 break;
169 case MLX5_CMD_OP_MODIFY_CQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300170 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ,
171 MLX5_GET(modify_cq_in, in, cqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300172 break;
173 case MLX5_CMD_OP_QUERY_SQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300174 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ,
175 MLX5_GET(query_sq_in, in, sqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300176 break;
177 case MLX5_CMD_OP_MODIFY_SQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300178 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ,
179 MLX5_GET(modify_sq_in, in, sqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300180 break;
181 case MLX5_CMD_OP_QUERY_RQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300182 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
183 MLX5_GET(query_rq_in, in, rqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300184 break;
185 case MLX5_CMD_OP_MODIFY_RQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300186 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
187 MLX5_GET(modify_rq_in, in, rqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300188 break;
189 case MLX5_CMD_OP_QUERY_RMP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300190 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP,
191 MLX5_GET(query_rmp_in, in, rmpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300192 break;
193 case MLX5_CMD_OP_MODIFY_RMP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300194 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP,
195 MLX5_GET(modify_rmp_in, in, rmpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300196 break;
197 case MLX5_CMD_OP_QUERY_RQT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300198 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT,
199 MLX5_GET(query_rqt_in, in, rqtn));
Yishai Hadase662e142018-06-17 13:00:02 +0300200 break;
201 case MLX5_CMD_OP_MODIFY_RQT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300202 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT,
203 MLX5_GET(modify_rqt_in, in, rqtn));
Yishai Hadase662e142018-06-17 13:00:02 +0300204 break;
205 case MLX5_CMD_OP_QUERY_TIR:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300206 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR,
207 MLX5_GET(query_tir_in, in, tirn));
Yishai Hadase662e142018-06-17 13:00:02 +0300208 break;
209 case MLX5_CMD_OP_MODIFY_TIR:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300210 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR,
211 MLX5_GET(modify_tir_in, in, tirn));
Yishai Hadase662e142018-06-17 13:00:02 +0300212 break;
213 case MLX5_CMD_OP_QUERY_TIS:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300214 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS,
215 MLX5_GET(query_tis_in, in, tisn));
Yishai Hadase662e142018-06-17 13:00:02 +0300216 break;
217 case MLX5_CMD_OP_MODIFY_TIS:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300218 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS,
219 MLX5_GET(modify_tis_in, in, tisn));
Yishai Hadase662e142018-06-17 13:00:02 +0300220 break;
221 case MLX5_CMD_OP_QUERY_FLOW_TABLE:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300222 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE,
223 MLX5_GET(query_flow_table_in, in,
224 table_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300225 break;
226 case MLX5_CMD_OP_MODIFY_FLOW_TABLE:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300227 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE,
228 MLX5_GET(modify_flow_table_in, in,
229 table_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300230 break;
231 case MLX5_CMD_OP_QUERY_FLOW_GROUP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300232 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_GROUP,
233 MLX5_GET(query_flow_group_in, in,
234 group_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300235 break;
236 case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300237 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY,
238 MLX5_GET(query_fte_in, in,
239 flow_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300240 break;
241 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300242 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY,
243 MLX5_GET(set_fte_in, in, flow_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300244 break;
245 case MLX5_CMD_OP_QUERY_Q_COUNTER:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300246 obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_Q_COUNTER,
247 MLX5_GET(query_q_counter_in, in,
248 counter_set_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300249 break;
250 case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300251 obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_FLOW_COUNTER,
252 MLX5_GET(query_flow_counter_in, in,
253 flow_counter_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300254 break;
255 case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300256 obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT,
257 MLX5_GET(general_obj_in_cmd_hdr, in,
258 obj_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300259 break;
260 case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300261 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT,
262 MLX5_GET(query_scheduling_element_in,
263 in, scheduling_element_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300264 break;
265 case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300266 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT,
267 MLX5_GET(modify_scheduling_element_in,
268 in, scheduling_element_id));
Yishai Hadase662e142018-06-17 13:00:02 +0300269 break;
270 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300271 obj_id = get_enc_obj_id(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT,
272 MLX5_GET(add_vxlan_udp_dport_in, in,
273 vxlan_udp_port));
Yishai Hadase662e142018-06-17 13:00:02 +0300274 break;
275 case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300276 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY,
277 MLX5_GET(query_l2_table_entry_in, in,
278 table_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300279 break;
280 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300281 obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY,
282 MLX5_GET(set_l2_table_entry_in, in,
283 table_index));
Yishai Hadase662e142018-06-17 13:00:02 +0300284 break;
285 case MLX5_CMD_OP_QUERY_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300286 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
287 MLX5_GET(query_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300288 break;
289 case MLX5_CMD_OP_RST2INIT_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300290 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
291 MLX5_GET(rst2init_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300292 break;
293 case MLX5_CMD_OP_INIT2RTR_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300294 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
295 MLX5_GET(init2rtr_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300296 break;
297 case MLX5_CMD_OP_RTR2RTS_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300298 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
299 MLX5_GET(rtr2rts_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300300 break;
301 case MLX5_CMD_OP_RTS2RTS_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300302 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
303 MLX5_GET(rts2rts_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300304 break;
305 case MLX5_CMD_OP_SQERR2RTS_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300306 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
307 MLX5_GET(sqerr2rts_qp_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300308 break;
309 case MLX5_CMD_OP_2ERR_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300310 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
311 MLX5_GET(qp_2err_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300312 break;
313 case MLX5_CMD_OP_2RST_QP:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300314 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
315 MLX5_GET(qp_2rst_in, in, qpn));
Yishai Hadase662e142018-06-17 13:00:02 +0300316 break;
317 case MLX5_CMD_OP_QUERY_DCT:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300318 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
319 MLX5_GET(query_dct_in, in, dctn));
Yishai Hadase662e142018-06-17 13:00:02 +0300320 break;
321 case MLX5_CMD_OP_QUERY_XRQ:
Yishai Hadas719598c2018-11-26 08:28:37 +0200322 case MLX5_CMD_OP_QUERY_XRQ_DC_PARAMS_ENTRY:
323 case MLX5_CMD_OP_QUERY_XRQ_ERROR_PARAMS:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300324 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ,
325 MLX5_GET(query_xrq_in, in, xrqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300326 break;
327 case MLX5_CMD_OP_QUERY_XRC_SRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300328 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ,
329 MLX5_GET(query_xrc_srq_in, in,
330 xrc_srqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300331 break;
332 case MLX5_CMD_OP_ARM_XRC_SRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300333 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ,
334 MLX5_GET(arm_xrc_srq_in, in, xrc_srqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300335 break;
336 case MLX5_CMD_OP_QUERY_SRQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300337 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SRQ,
338 MLX5_GET(query_srq_in, in, srqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300339 break;
340 case MLX5_CMD_OP_ARM_RQ:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300341 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
342 MLX5_GET(arm_rq_in, in, srq_number));
Yishai Hadase662e142018-06-17 13:00:02 +0300343 break;
344 case MLX5_CMD_OP_DRAIN_DCT:
345 case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300346 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
347 MLX5_GET(drain_dct_in, in, dctn));
Yishai Hadase662e142018-06-17 13:00:02 +0300348 break;
349 case MLX5_CMD_OP_ARM_XRQ:
Yishai Hadas719598c2018-11-26 08:28:37 +0200350 case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY:
Yishai Hadas2351776e2018-10-07 12:06:34 +0300351 obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ,
352 MLX5_GET(arm_xrq_in, in, xrqn));
Yishai Hadase662e142018-06-17 13:00:02 +0300353 break;
Yishai Hadas719598c2018-11-26 08:28:37 +0200354 case MLX5_CMD_OP_QUERY_PACKET_REFORMAT_CONTEXT:
355 obj_id = get_enc_obj_id
356 (MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT,
357 MLX5_GET(query_packet_reformat_context_in,
358 in, packet_reformat_id));
359 break;
Yishai Hadase662e142018-06-17 13:00:02 +0300360 default:
Yishai Hadas34613eb2018-11-26 08:28:35 +0200361 obj_id = 0;
Yishai Hadase662e142018-06-17 13:00:02 +0300362 }
363
Yishai Hadas34613eb2018-11-26 08:28:35 +0200364 return obj_id;
365}
Yishai Hadase662e142018-06-17 13:00:02 +0300366
Yishai Hadas34613eb2018-11-26 08:28:35 +0200367static bool devx_is_valid_obj_id(struct ib_uobject *uobj, const void *in)
368{
369 u64 obj_id = devx_get_obj_id(in);
370
371 if (!obj_id)
372 return false;
373
374 switch (uobj_get_object_id(uobj)) {
375 case UVERBS_OBJECT_CQ:
376 return get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ,
377 to_mcq(uobj->object)->mcq.cqn) ==
378 obj_id;
379
380 case UVERBS_OBJECT_SRQ:
381 {
382 struct mlx5_core_srq *srq = &(to_msrq(uobj->object)->msrq);
383 struct mlx5_ib_dev *dev = to_mdev(uobj->context->device);
384 u16 opcode;
385
386 switch (srq->common.res) {
387 case MLX5_RES_XSRQ:
388 opcode = MLX5_CMD_OP_CREATE_XRC_SRQ;
389 break;
390 case MLX5_RES_XRQ:
391 opcode = MLX5_CMD_OP_CREATE_XRQ;
392 break;
393 default:
394 if (!dev->mdev->issi)
395 opcode = MLX5_CMD_OP_CREATE_SRQ;
396 else
397 opcode = MLX5_CMD_OP_CREATE_RMP;
398 }
399
400 return get_enc_obj_id(opcode,
401 to_msrq(uobj->object)->msrq.srqn) ==
402 obj_id;
403 }
404
405 case UVERBS_OBJECT_QP:
406 {
407 struct mlx5_ib_qp *qp = to_mqp(uobj->object);
408 enum ib_qp_type qp_type = qp->ibqp.qp_type;
409
410 if (qp_type == IB_QPT_RAW_PACKET ||
411 (qp->flags & MLX5_IB_QP_UNDERLAY)) {
412 struct mlx5_ib_raw_packet_qp *raw_packet_qp =
413 &qp->raw_packet_qp;
414 struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
415 struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
416
417 return (get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
418 rq->base.mqp.qpn) == obj_id ||
419 get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ,
420 sq->base.mqp.qpn) == obj_id ||
421 get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR,
422 rq->tirn) == obj_id ||
423 get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS,
424 sq->tisn) == obj_id);
425 }
426
427 if (qp_type == MLX5_IB_QPT_DCT)
428 return get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT,
429 qp->dct.mdct.mqp.qpn) == obj_id;
430
431 return get_enc_obj_id(MLX5_CMD_OP_CREATE_QP,
432 qp->ibqp.qp_num) == obj_id;
433 }
434
435 case UVERBS_OBJECT_WQ:
436 return get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ,
437 to_mrwq(uobj->object)->core_qp.qpn) ==
438 obj_id;
439
440 case UVERBS_OBJECT_RWQ_IND_TBL:
441 return get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT,
442 to_mrwq_ind_table(uobj->object)->rqtn) ==
443 obj_id;
444
445 case MLX5_IB_OBJECT_DEVX_OBJ:
446 return ((struct devx_obj *)uobj->object)->obj_id == obj_id;
447
Yishai Hadase662e142018-06-17 13:00:02 +0300448 default:
449 return false;
450 }
Yishai Hadase662e142018-06-17 13:00:02 +0300451}
452
Yishai Hadasba1a0572018-09-20 21:39:33 +0300453static void devx_set_umem_valid(const void *in)
454{
455 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
456
457 switch (opcode) {
458 case MLX5_CMD_OP_CREATE_MKEY:
459 MLX5_SET(create_mkey_in, in, mkey_umem_valid, 1);
460 break;
461 case MLX5_CMD_OP_CREATE_CQ:
462 {
463 void *cqc;
464
465 MLX5_SET(create_cq_in, in, cq_umem_valid, 1);
466 cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
467 MLX5_SET(cqc, cqc, dbr_umem_valid, 1);
468 break;
469 }
470 case MLX5_CMD_OP_CREATE_QP:
471 {
472 void *qpc;
473
474 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
475 MLX5_SET(qpc, qpc, dbr_umem_valid, 1);
476 MLX5_SET(create_qp_in, in, wq_umem_valid, 1);
477 break;
478 }
479
480 case MLX5_CMD_OP_CREATE_RQ:
481 {
482 void *rqc, *wq;
483
484 rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
485 wq = MLX5_ADDR_OF(rqc, rqc, wq);
486 MLX5_SET(wq, wq, dbr_umem_valid, 1);
487 MLX5_SET(wq, wq, wq_umem_valid, 1);
488 break;
489 }
490
491 case MLX5_CMD_OP_CREATE_SQ:
492 {
493 void *sqc, *wq;
494
495 sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
496 wq = MLX5_ADDR_OF(sqc, sqc, wq);
497 MLX5_SET(wq, wq, dbr_umem_valid, 1);
498 MLX5_SET(wq, wq, wq_umem_valid, 1);
499 break;
500 }
501
502 case MLX5_CMD_OP_MODIFY_CQ:
503 MLX5_SET(modify_cq_in, in, cq_umem_valid, 1);
504 break;
505
506 case MLX5_CMD_OP_CREATE_RMP:
507 {
508 void *rmpc, *wq;
509
510 rmpc = MLX5_ADDR_OF(create_rmp_in, in, ctx);
511 wq = MLX5_ADDR_OF(rmpc, rmpc, wq);
512 MLX5_SET(wq, wq, dbr_umem_valid, 1);
513 MLX5_SET(wq, wq, wq_umem_valid, 1);
514 break;
515 }
516
517 case MLX5_CMD_OP_CREATE_XRQ:
518 {
519 void *xrqc, *wq;
520
521 xrqc = MLX5_ADDR_OF(create_xrq_in, in, xrq_context);
522 wq = MLX5_ADDR_OF(xrqc, xrqc, wq);
523 MLX5_SET(wq, wq, dbr_umem_valid, 1);
524 MLX5_SET(wq, wq, wq_umem_valid, 1);
525 break;
526 }
527
528 case MLX5_CMD_OP_CREATE_XRC_SRQ:
529 {
530 void *xrc_srqc;
531
532 MLX5_SET(create_xrc_srq_in, in, xrc_srq_umem_valid, 1);
533 xrc_srqc = MLX5_ADDR_OF(create_xrc_srq_in, in,
534 xrc_srq_context_entry);
535 MLX5_SET(xrc_srqc, xrc_srqc, dbr_umem_valid, 1);
536 break;
537 }
538
539 default:
540 return;
541 }
542}
543
Yishai Hadas2351776e2018-10-07 12:06:34 +0300544static bool devx_is_obj_create_cmd(const void *in, u16 *opcode)
Yishai Hadas7efce362018-06-17 13:00:01 +0300545{
Yishai Hadas2351776e2018-10-07 12:06:34 +0300546 *opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
Yishai Hadas7efce362018-06-17 13:00:01 +0300547
Yishai Hadas2351776e2018-10-07 12:06:34 +0300548 switch (*opcode) {
Yishai Hadas7efce362018-06-17 13:00:01 +0300549 case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
550 case MLX5_CMD_OP_CREATE_MKEY:
551 case MLX5_CMD_OP_CREATE_CQ:
552 case MLX5_CMD_OP_ALLOC_PD:
553 case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN:
554 case MLX5_CMD_OP_CREATE_RMP:
555 case MLX5_CMD_OP_CREATE_SQ:
556 case MLX5_CMD_OP_CREATE_RQ:
557 case MLX5_CMD_OP_CREATE_RQT:
558 case MLX5_CMD_OP_CREATE_TIR:
559 case MLX5_CMD_OP_CREATE_TIS:
560 case MLX5_CMD_OP_ALLOC_Q_COUNTER:
561 case MLX5_CMD_OP_CREATE_FLOW_TABLE:
562 case MLX5_CMD_OP_CREATE_FLOW_GROUP:
563 case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
Mark Bloch60786f02018-08-28 14:18:46 +0300564 case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT:
Yishai Hadas7efce362018-06-17 13:00:01 +0300565 case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
566 case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
567 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
568 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
569 case MLX5_CMD_OP_CREATE_QP:
570 case MLX5_CMD_OP_CREATE_SRQ:
571 case MLX5_CMD_OP_CREATE_XRC_SRQ:
572 case MLX5_CMD_OP_CREATE_DCT:
573 case MLX5_CMD_OP_CREATE_XRQ:
574 case MLX5_CMD_OP_ATTACH_TO_MCG:
575 case MLX5_CMD_OP_ALLOC_XRCD:
576 return true;
577 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
578 {
579 u16 op_mod = MLX5_GET(set_fte_in, in, op_mod);
580 if (op_mod == 0)
581 return true;
582 return false;
583 }
584 default:
585 return false;
586 }
587}
588
Yishai Hadase662e142018-06-17 13:00:02 +0300589static bool devx_is_obj_modify_cmd(const void *in)
590{
591 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
592
593 switch (opcode) {
594 case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
595 case MLX5_CMD_OP_MODIFY_CQ:
596 case MLX5_CMD_OP_MODIFY_RMP:
597 case MLX5_CMD_OP_MODIFY_SQ:
598 case MLX5_CMD_OP_MODIFY_RQ:
599 case MLX5_CMD_OP_MODIFY_RQT:
600 case MLX5_CMD_OP_MODIFY_TIR:
601 case MLX5_CMD_OP_MODIFY_TIS:
602 case MLX5_CMD_OP_MODIFY_FLOW_TABLE:
603 case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT:
604 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
605 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
606 case MLX5_CMD_OP_RST2INIT_QP:
607 case MLX5_CMD_OP_INIT2RTR_QP:
608 case MLX5_CMD_OP_RTR2RTS_QP:
609 case MLX5_CMD_OP_RTS2RTS_QP:
610 case MLX5_CMD_OP_SQERR2RTS_QP:
611 case MLX5_CMD_OP_2ERR_QP:
612 case MLX5_CMD_OP_2RST_QP:
613 case MLX5_CMD_OP_ARM_XRC_SRQ:
614 case MLX5_CMD_OP_ARM_RQ:
615 case MLX5_CMD_OP_DRAIN_DCT:
616 case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
617 case MLX5_CMD_OP_ARM_XRQ:
Yishai Hadas719598c2018-11-26 08:28:37 +0200618 case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY:
Yishai Hadase662e142018-06-17 13:00:02 +0300619 return true;
620 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
621 {
622 u16 op_mod = MLX5_GET(set_fte_in, in, op_mod);
623
624 if (op_mod == 1)
625 return true;
626 return false;
627 }
628 default:
629 return false;
630 }
631}
632
633static bool devx_is_obj_query_cmd(const void *in)
634{
635 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
636
637 switch (opcode) {
638 case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
639 case MLX5_CMD_OP_QUERY_MKEY:
640 case MLX5_CMD_OP_QUERY_CQ:
641 case MLX5_CMD_OP_QUERY_RMP:
642 case MLX5_CMD_OP_QUERY_SQ:
643 case MLX5_CMD_OP_QUERY_RQ:
644 case MLX5_CMD_OP_QUERY_RQT:
645 case MLX5_CMD_OP_QUERY_TIR:
646 case MLX5_CMD_OP_QUERY_TIS:
647 case MLX5_CMD_OP_QUERY_Q_COUNTER:
648 case MLX5_CMD_OP_QUERY_FLOW_TABLE:
649 case MLX5_CMD_OP_QUERY_FLOW_GROUP:
650 case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
651 case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
652 case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT:
653 case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
654 case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY:
655 case MLX5_CMD_OP_QUERY_QP:
656 case MLX5_CMD_OP_QUERY_SRQ:
657 case MLX5_CMD_OP_QUERY_XRC_SRQ:
658 case MLX5_CMD_OP_QUERY_DCT:
659 case MLX5_CMD_OP_QUERY_XRQ:
Yishai Hadas719598c2018-11-26 08:28:37 +0200660 case MLX5_CMD_OP_QUERY_XRQ_DC_PARAMS_ENTRY:
661 case MLX5_CMD_OP_QUERY_XRQ_ERROR_PARAMS:
662 case MLX5_CMD_OP_QUERY_PACKET_REFORMAT_CONTEXT:
Yishai Hadase662e142018-06-17 13:00:02 +0300663 return true;
664 default:
665 return false;
666 }
667}
668
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300669static bool devx_is_whitelist_cmd(void *in)
670{
671 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
672
673 switch (opcode) {
674 case MLX5_CMD_OP_QUERY_HCA_CAP:
675 case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT:
676 return true;
677 default:
678 return false;
679 }
680}
681
682static int devx_get_uid(struct mlx5_ib_ucontext *c, void *cmd_in)
683{
684 if (devx_is_whitelist_cmd(cmd_in)) {
685 struct mlx5_ib_dev *dev;
686
687 if (c->devx_uid)
688 return c->devx_uid;
689
690 dev = to_mdev(c->ibucontext.device);
691 if (dev->devx_whitelist_uid)
692 return dev->devx_whitelist_uid;
693
694 return -EOPNOTSUPP;
695 }
696
697 if (!c->devx_uid)
698 return -EINVAL;
699
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300700 return c->devx_uid;
701}
Yishai Hadase662e142018-06-17 13:00:02 +0300702static bool devx_is_general_cmd(void *in)
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300703{
704 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
705
Yishai Hadas719598c2018-11-26 08:28:37 +0200706 if (opcode >= MLX5_CMD_OP_GENERAL_START &&
707 opcode < MLX5_CMD_OP_GENERAL_END)
708 return true;
709
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300710 switch (opcode) {
711 case MLX5_CMD_OP_QUERY_HCA_CAP:
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300712 case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT:
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300713 case MLX5_CMD_OP_QUERY_VPORT_STATE:
714 case MLX5_CMD_OP_QUERY_ADAPTER:
715 case MLX5_CMD_OP_QUERY_ISSI:
716 case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT:
717 case MLX5_CMD_OP_QUERY_ROCE_ADDRESS:
718 case MLX5_CMD_OP_QUERY_VNIC_ENV:
719 case MLX5_CMD_OP_QUERY_VPORT_COUNTER:
720 case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG:
721 case MLX5_CMD_OP_NOP:
722 case MLX5_CMD_OP_QUERY_CONG_STATUS:
723 case MLX5_CMD_OP_QUERY_CONG_PARAMS:
724 case MLX5_CMD_OP_QUERY_CONG_STATISTICS:
725 return true;
726 default:
727 return false;
728 }
729}
730
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600731static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_EQN)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200732 struct uverbs_attr_bundle *attrs)
Yishai Hadasf6fe01b2018-06-17 13:00:05 +0300733{
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600734 struct mlx5_ib_ucontext *c;
735 struct mlx5_ib_dev *dev;
Yishai Hadasf6fe01b2018-06-17 13:00:05 +0300736 int user_vector;
737 int dev_eqn;
738 unsigned int irqn;
739 int err;
740
741 if (uverbs_copy_from(&user_vector, attrs,
742 MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC))
743 return -EFAULT;
744
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200745 c = devx_ufile2uctx(attrs);
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600746 if (IS_ERR(c))
747 return PTR_ERR(c);
748 dev = to_mdev(c->ibucontext.device);
749
Yishai Hadasf6fe01b2018-06-17 13:00:05 +0300750 err = mlx5_vector2eqn(dev->mdev, user_vector, &dev_eqn, &irqn);
751 if (err < 0)
752 return err;
753
754 if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN,
755 &dev_eqn, sizeof(dev_eqn)))
756 return -EFAULT;
757
758 return 0;
759}
760
Yishai Hadas7c043e92018-06-17 13:00:03 +0300761/*
762 *Security note:
763 * The hardware protection mechanism works like this: Each device object that
764 * is subject to UAR doorbells (QP/SQ/CQ) gets a UAR ID (called uar_page in
765 * the device specification manual) upon its creation. Then upon doorbell,
766 * hardware fetches the object context for which the doorbell was rang, and
767 * validates that the UAR through which the DB was rang matches the UAR ID
768 * of the object.
769 * If no match the doorbell is silently ignored by the hardware. Of course,
770 * the user cannot ring a doorbell on a UAR that was not mapped to it.
771 * Now in devx, as the devx kernel does not manipulate the QP/SQ/CQ command
772 * mailboxes (except tagging them with UID), we expose to the user its UAR
773 * ID, so it can embed it in these objects in the expected specification
774 * format. So the only thing the user can do is hurt itself by creating a
775 * QP/SQ/CQ with a UAR ID other than his, and then in this case other users
776 * may ring a doorbell on its objects.
777 * The consequence of that will be that another user can schedule a QP/SQ
778 * of the buggy user for execution (just insert it to the hardware schedule
779 * queue or arm its CQ for event generation), no further harm is expected.
780 */
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600781static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_UAR)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200782 struct uverbs_attr_bundle *attrs)
Yishai Hadas7c043e92018-06-17 13:00:03 +0300783{
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600784 struct mlx5_ib_ucontext *c;
785 struct mlx5_ib_dev *dev;
Yishai Hadas7c043e92018-06-17 13:00:03 +0300786 u32 user_idx;
787 s32 dev_idx;
788
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200789 c = devx_ufile2uctx(attrs);
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600790 if (IS_ERR(c))
791 return PTR_ERR(c);
792 dev = to_mdev(c->ibucontext.device);
793
Yishai Hadas7c043e92018-06-17 13:00:03 +0300794 if (uverbs_copy_from(&user_idx, attrs,
795 MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX))
796 return -EFAULT;
797
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600798 dev_idx = bfregn_to_uar_index(dev, &c->bfregi, user_idx, true);
Yishai Hadas7c043e92018-06-17 13:00:03 +0300799 if (dev_idx < 0)
800 return dev_idx;
801
802 if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX,
803 &dev_idx, sizeof(dev_idx)))
804 return -EFAULT;
805
806 return 0;
807}
808
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -0600809static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200810 struct uverbs_attr_bundle *attrs)
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300811{
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600812 struct mlx5_ib_ucontext *c;
813 struct mlx5_ib_dev *dev;
Yishai Hadas7efce362018-06-17 13:00:01 +0300814 void *cmd_in = uverbs_attr_get_alloced_ptr(
815 attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300816 int cmd_out_len = uverbs_attr_get_len(attrs,
817 MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT);
818 void *cmd_out;
819 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300820 int uid;
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300821
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +0200822 c = devx_ufile2uctx(attrs);
Jason Gunthorpe22fa27f2018-07-10 13:43:06 -0600823 if (IS_ERR(c))
824 return PTR_ERR(c);
825 dev = to_mdev(c->ibucontext.device);
826
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300827 uid = devx_get_uid(c, cmd_in);
828 if (uid < 0)
829 return uid;
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300830
831 /* Only white list of some general HCA commands are allowed for this method. */
832 if (!devx_is_general_cmd(cmd_in))
833 return -EINVAL;
834
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600835 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
836 if (IS_ERR(cmd_out))
837 return PTR_ERR(cmd_out);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300838
Yishai Hadas7e1335a2018-09-20 21:45:20 +0300839 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300840 err = mlx5_cmd_exec(dev->mdev, cmd_in,
841 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN),
842 cmd_out, cmd_out_len);
843 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600844 return err;
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300845
Jason Gunthorpeb61815e2018-08-09 20:14:41 -0600846 return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out,
847 cmd_out_len);
Yishai Hadas8aa8c952018-06-17 13:00:00 +0300848}
849
Yishai Hadas7efce362018-06-17 13:00:01 +0300850static void devx_obj_build_destroy_cmd(void *in, void *out, void *din,
851 u32 *dinlen,
852 u32 *obj_id)
853{
854 u16 obj_type = MLX5_GET(general_obj_in_cmd_hdr, in, obj_type);
855 u16 uid = MLX5_GET(general_obj_in_cmd_hdr, in, uid);
856
857 *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
858 *dinlen = MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr);
859
860 MLX5_SET(general_obj_in_cmd_hdr, din, obj_id, *obj_id);
861 MLX5_SET(general_obj_in_cmd_hdr, din, uid, uid);
862
863 switch (MLX5_GET(general_obj_in_cmd_hdr, in, opcode)) {
864 case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
865 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
866 MLX5_SET(general_obj_in_cmd_hdr, din, obj_type, obj_type);
867 break;
868
Yishai Hadas6e3722b2018-12-19 16:28:15 +0200869 case MLX5_CMD_OP_CREATE_UMEM:
870 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
871 MLX5_CMD_OP_DESTROY_UMEM);
872 break;
Yishai Hadas7efce362018-06-17 13:00:01 +0300873 case MLX5_CMD_OP_CREATE_MKEY:
874 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_MKEY);
875 break;
876 case MLX5_CMD_OP_CREATE_CQ:
877 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_CQ);
878 break;
879 case MLX5_CMD_OP_ALLOC_PD:
880 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_PD);
881 break;
882 case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN:
883 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
884 MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN);
885 break;
886 case MLX5_CMD_OP_CREATE_RMP:
887 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RMP);
888 break;
889 case MLX5_CMD_OP_CREATE_SQ:
890 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SQ);
891 break;
892 case MLX5_CMD_OP_CREATE_RQ:
893 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQ);
894 break;
895 case MLX5_CMD_OP_CREATE_RQT:
896 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT);
897 break;
898 case MLX5_CMD_OP_CREATE_TIR:
899 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIR);
900 break;
901 case MLX5_CMD_OP_CREATE_TIS:
902 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS);
903 break;
904 case MLX5_CMD_OP_ALLOC_Q_COUNTER:
905 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
906 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
907 break;
908 case MLX5_CMD_OP_CREATE_FLOW_TABLE:
909 *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_table_in);
910 *obj_id = MLX5_GET(create_flow_table_out, out, table_id);
911 MLX5_SET(destroy_flow_table_in, din, other_vport,
912 MLX5_GET(create_flow_table_in, in, other_vport));
913 MLX5_SET(destroy_flow_table_in, din, vport_number,
914 MLX5_GET(create_flow_table_in, in, vport_number));
915 MLX5_SET(destroy_flow_table_in, din, table_type,
916 MLX5_GET(create_flow_table_in, in, table_type));
917 MLX5_SET(destroy_flow_table_in, din, table_id, *obj_id);
918 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
919 MLX5_CMD_OP_DESTROY_FLOW_TABLE);
920 break;
921 case MLX5_CMD_OP_CREATE_FLOW_GROUP:
922 *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_group_in);
923 *obj_id = MLX5_GET(create_flow_group_out, out, group_id);
924 MLX5_SET(destroy_flow_group_in, din, other_vport,
925 MLX5_GET(create_flow_group_in, in, other_vport));
926 MLX5_SET(destroy_flow_group_in, din, vport_number,
927 MLX5_GET(create_flow_group_in, in, vport_number));
928 MLX5_SET(destroy_flow_group_in, din, table_type,
929 MLX5_GET(create_flow_group_in, in, table_type));
930 MLX5_SET(destroy_flow_group_in, din, table_id,
931 MLX5_GET(create_flow_group_in, in, table_id));
932 MLX5_SET(destroy_flow_group_in, din, group_id, *obj_id);
933 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
934 MLX5_CMD_OP_DESTROY_FLOW_GROUP);
935 break;
936 case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
937 *dinlen = MLX5_ST_SZ_BYTES(delete_fte_in);
938 *obj_id = MLX5_GET(set_fte_in, in, flow_index);
939 MLX5_SET(delete_fte_in, din, other_vport,
940 MLX5_GET(set_fte_in, in, other_vport));
941 MLX5_SET(delete_fte_in, din, vport_number,
942 MLX5_GET(set_fte_in, in, vport_number));
943 MLX5_SET(delete_fte_in, din, table_type,
944 MLX5_GET(set_fte_in, in, table_type));
945 MLX5_SET(delete_fte_in, din, table_id,
946 MLX5_GET(set_fte_in, in, table_id));
947 MLX5_SET(delete_fte_in, din, flow_index, *obj_id);
948 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
949 MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
950 break;
951 case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
952 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
953 MLX5_CMD_OP_DEALLOC_FLOW_COUNTER);
954 break;
Mark Bloch60786f02018-08-28 14:18:46 +0300955 case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT:
Yishai Hadas7efce362018-06-17 13:00:01 +0300956 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
Mark Bloch60786f02018-08-28 14:18:46 +0300957 MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
Yishai Hadas7efce362018-06-17 13:00:01 +0300958 break;
959 case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
960 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
961 MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
962 break;
963 case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
964 *dinlen = MLX5_ST_SZ_BYTES(destroy_scheduling_element_in);
965 *obj_id = MLX5_GET(create_scheduling_element_out, out,
966 scheduling_element_id);
967 MLX5_SET(destroy_scheduling_element_in, din,
968 scheduling_hierarchy,
969 MLX5_GET(create_scheduling_element_in, in,
970 scheduling_hierarchy));
971 MLX5_SET(destroy_scheduling_element_in, din,
972 scheduling_element_id, *obj_id);
973 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
974 MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT);
975 break;
976 case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
977 *dinlen = MLX5_ST_SZ_BYTES(delete_vxlan_udp_dport_in);
978 *obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port);
979 MLX5_SET(delete_vxlan_udp_dport_in, din, vxlan_udp_port, *obj_id);
980 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
981 MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
982 break;
983 case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
984 *dinlen = MLX5_ST_SZ_BYTES(delete_l2_table_entry_in);
985 *obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index);
986 MLX5_SET(delete_l2_table_entry_in, din, table_index, *obj_id);
987 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
988 MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY);
989 break;
990 case MLX5_CMD_OP_CREATE_QP:
991 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_QP);
992 break;
993 case MLX5_CMD_OP_CREATE_SRQ:
994 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SRQ);
995 break;
996 case MLX5_CMD_OP_CREATE_XRC_SRQ:
997 MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
998 MLX5_CMD_OP_DESTROY_XRC_SRQ);
999 break;
1000 case MLX5_CMD_OP_CREATE_DCT:
1001 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_DCT);
1002 break;
1003 case MLX5_CMD_OP_CREATE_XRQ:
1004 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_XRQ);
1005 break;
1006 case MLX5_CMD_OP_ATTACH_TO_MCG:
1007 *dinlen = MLX5_ST_SZ_BYTES(detach_from_mcg_in);
1008 MLX5_SET(detach_from_mcg_in, din, qpn,
1009 MLX5_GET(attach_to_mcg_in, in, qpn));
1010 memcpy(MLX5_ADDR_OF(detach_from_mcg_in, din, multicast_gid),
1011 MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid),
1012 MLX5_FLD_SZ_BYTES(attach_to_mcg_in, multicast_gid));
1013 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DETACH_FROM_MCG);
1014 break;
1015 case MLX5_CMD_OP_ALLOC_XRCD:
1016 MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
1017 break;
1018 default:
1019 /* The entry must match to one of the devx_is_obj_create_cmd */
1020 WARN_ON(true);
1021 break;
1022 }
1023}
1024
1025static int devx_obj_cleanup(struct ib_uobject *uobject,
1026 enum rdma_remove_reason why)
1027{
1028 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
1029 struct devx_obj *obj = uobject->object;
1030 int ret;
1031
1032 ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
Yishai Hadas1c774832018-06-20 17:11:39 +03001033 if (ib_is_destroy_retryable(ret, why, uobject))
Yishai Hadas7efce362018-06-17 13:00:01 +03001034 return ret;
1035
1036 kfree(obj);
1037 return ret;
1038}
1039
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -06001040static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +02001041 struct uverbs_attr_bundle *attrs)
Yishai Hadas7efce362018-06-17 13:00:01 +03001042{
Yishai Hadas7efce362018-06-17 13:00:01 +03001043 void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN);
1044 int cmd_out_len = uverbs_attr_get_len(attrs,
1045 MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT);
1046 void *cmd_out;
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001047 struct ib_uobject *uobj = uverbs_attr_get_uobject(
1048 attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE);
1049 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
1050 struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device);
Yishai Hadase8ef0902018-09-25 12:11:12 +03001051 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
Yishai Hadas7efce362018-06-17 13:00:01 +03001052 struct devx_obj *obj;
1053 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001054 int uid;
Yishai Hadas2351776e2018-10-07 12:06:34 +03001055 u32 obj_id;
1056 u16 opcode;
Yishai Hadas7efce362018-06-17 13:00:01 +03001057
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001058 uid = devx_get_uid(c, cmd_in);
1059 if (uid < 0)
1060 return uid;
Yishai Hadas7efce362018-06-17 13:00:01 +03001061
Yishai Hadas2351776e2018-10-07 12:06:34 +03001062 if (!devx_is_obj_create_cmd(cmd_in, &opcode))
Yishai Hadas7efce362018-06-17 13:00:01 +03001063 return -EINVAL;
1064
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001065 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
1066 if (IS_ERR(cmd_out))
1067 return PTR_ERR(cmd_out);
1068
Yishai Hadas7efce362018-06-17 13:00:01 +03001069 obj = kzalloc(sizeof(struct devx_obj), GFP_KERNEL);
1070 if (!obj)
1071 return -ENOMEM;
1072
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001073 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Yishai Hadasba1a0572018-09-20 21:39:33 +03001074 devx_set_umem_valid(cmd_in);
1075
Yishai Hadas7efce362018-06-17 13:00:01 +03001076 err = mlx5_cmd_exec(dev->mdev, cmd_in,
1077 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN),
1078 cmd_out, cmd_out_len);
1079 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001080 goto obj_free;
Yishai Hadas7efce362018-06-17 13:00:01 +03001081
Yishai Hadas7efce362018-06-17 13:00:01 +03001082 uobj->object = obj;
1083 obj->mdev = dev->mdev;
Yishai Hadas2351776e2018-10-07 12:06:34 +03001084 devx_obj_build_destroy_cmd(cmd_in, cmd_out, obj->dinbox, &obj->dinlen,
1085 &obj_id);
Yishai Hadas7efce362018-06-17 13:00:01 +03001086 WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32));
1087
1088 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len);
1089 if (err)
Yishai Hadase8ef0902018-09-25 12:11:12 +03001090 goto obj_destroy;
Yishai Hadas7efce362018-06-17 13:00:01 +03001091
Yishai Hadas2351776e2018-10-07 12:06:34 +03001092 obj->obj_id = get_enc_obj_id(opcode, obj_id);
Yishai Hadas7efce362018-06-17 13:00:01 +03001093 return 0;
1094
Yishai Hadase8ef0902018-09-25 12:11:12 +03001095obj_destroy:
1096 mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
Yishai Hadas7efce362018-06-17 13:00:01 +03001097obj_free:
1098 kfree(obj);
1099 return err;
1100}
1101
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -06001102static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MODIFY)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +02001103 struct uverbs_attr_bundle *attrs)
Yishai Hadase662e142018-06-17 13:00:02 +03001104{
Yishai Hadase662e142018-06-17 13:00:02 +03001105 void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN);
1106 int cmd_out_len = uverbs_attr_get_len(attrs,
1107 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT);
1108 struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
1109 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE);
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001110 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
Yishai Hadas34613eb2018-11-26 08:28:35 +02001111 struct mlx5_ib_dev *mdev = to_mdev(uobj->context->device);
Yishai Hadase662e142018-06-17 13:00:02 +03001112 void *cmd_out;
1113 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001114 int uid;
Yishai Hadase662e142018-06-17 13:00:02 +03001115
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001116 uid = devx_get_uid(c, cmd_in);
1117 if (uid < 0)
1118 return uid;
Yishai Hadase662e142018-06-17 13:00:02 +03001119
1120 if (!devx_is_obj_modify_cmd(cmd_in))
1121 return -EINVAL;
1122
Yishai Hadas34613eb2018-11-26 08:28:35 +02001123 if (!devx_is_valid_obj_id(uobj, cmd_in))
Yishai Hadase662e142018-06-17 13:00:02 +03001124 return -EINVAL;
1125
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001126 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
1127 if (IS_ERR(cmd_out))
1128 return PTR_ERR(cmd_out);
Yishai Hadase662e142018-06-17 13:00:02 +03001129
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001130 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Yishai Hadasba1a0572018-09-20 21:39:33 +03001131 devx_set_umem_valid(cmd_in);
1132
Yishai Hadas34613eb2018-11-26 08:28:35 +02001133 err = mlx5_cmd_exec(mdev->mdev, cmd_in,
Yishai Hadase662e142018-06-17 13:00:02 +03001134 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN),
1135 cmd_out, cmd_out_len);
1136 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001137 return err;
Yishai Hadase662e142018-06-17 13:00:02 +03001138
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001139 return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
1140 cmd_out, cmd_out_len);
Yishai Hadase662e142018-06-17 13:00:02 +03001141}
1142
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -06001143static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +02001144 struct uverbs_attr_bundle *attrs)
Yishai Hadase662e142018-06-17 13:00:02 +03001145{
Yishai Hadase662e142018-06-17 13:00:02 +03001146 void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN);
1147 int cmd_out_len = uverbs_attr_get_len(attrs,
1148 MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT);
1149 struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
1150 MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE);
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001151 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
Yishai Hadase662e142018-06-17 13:00:02 +03001152 void *cmd_out;
1153 int err;
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001154 int uid;
Yishai Hadas34613eb2018-11-26 08:28:35 +02001155 struct mlx5_ib_dev *mdev = to_mdev(uobj->context->device);
Yishai Hadase662e142018-06-17 13:00:02 +03001156
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001157 uid = devx_get_uid(c, cmd_in);
1158 if (uid < 0)
1159 return uid;
Yishai Hadase662e142018-06-17 13:00:02 +03001160
1161 if (!devx_is_obj_query_cmd(cmd_in))
1162 return -EINVAL;
1163
Yishai Hadas34613eb2018-11-26 08:28:35 +02001164 if (!devx_is_valid_obj_id(uobj, cmd_in))
Yishai Hadase662e142018-06-17 13:00:02 +03001165 return -EINVAL;
1166
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001167 cmd_out = uverbs_zalloc(attrs, cmd_out_len);
1168 if (IS_ERR(cmd_out))
1169 return PTR_ERR(cmd_out);
Yishai Hadase662e142018-06-17 13:00:02 +03001170
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001171 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
Yishai Hadas34613eb2018-11-26 08:28:35 +02001172 err = mlx5_cmd_exec(mdev->mdev, cmd_in,
Yishai Hadase662e142018-06-17 13:00:02 +03001173 uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN),
1174 cmd_out, cmd_out_len);
1175 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001176 return err;
Yishai Hadase662e142018-06-17 13:00:02 +03001177
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001178 return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
1179 cmd_out, cmd_out_len);
Yishai Hadase662e142018-06-17 13:00:02 +03001180}
1181
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001182struct devx_async_event_queue {
1183 spinlock_t lock;
1184 wait_queue_head_t poll_wait;
1185 struct list_head event_list;
Yishai Hadasa124edb2019-01-22 08:29:57 +02001186 atomic_t bytes_in_use;
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001187};
1188
1189struct devx_async_cmd_event_file {
1190 struct ib_uobject uobj;
1191 struct devx_async_event_queue ev_queue;
Yishai Hadasa124edb2019-01-22 08:29:57 +02001192 struct mlx5_async_ctx async_ctx;
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001193};
1194
1195static void devx_init_event_queue(struct devx_async_event_queue *ev_queue)
1196{
1197 spin_lock_init(&ev_queue->lock);
1198 INIT_LIST_HEAD(&ev_queue->event_list);
1199 init_waitqueue_head(&ev_queue->poll_wait);
Yishai Hadasa124edb2019-01-22 08:29:57 +02001200 atomic_set(&ev_queue->bytes_in_use, 0);
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001201}
1202
1203static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC)(
1204 struct uverbs_attr_bundle *attrs)
1205{
1206 struct devx_async_cmd_event_file *ev_file;
1207
1208 struct ib_uobject *uobj = uverbs_attr_get_uobject(
1209 attrs, MLX5_IB_ATTR_DEVX_ASYNC_CMD_FD_ALLOC_HANDLE);
Yishai Hadasa124edb2019-01-22 08:29:57 +02001210 struct mlx5_ib_dev *mdev = to_mdev(uobj->context->device);
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001211
1212 ev_file = container_of(uobj, struct devx_async_cmd_event_file,
1213 uobj);
1214 devx_init_event_queue(&ev_file->ev_queue);
Yishai Hadasa124edb2019-01-22 08:29:57 +02001215 mlx5_cmd_init_async_ctx(mdev->mdev, &ev_file->async_ctx);
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001216 return 0;
1217}
1218
Yishai Hadasa124edb2019-01-22 08:29:57 +02001219static void devx_query_callback(int status, struct mlx5_async_work *context)
1220{
1221 struct devx_async_data *async_data =
1222 container_of(context, struct devx_async_data, cb_work);
1223 struct ib_uobject *fd_uobj = async_data->fd_uobj;
1224 struct devx_async_cmd_event_file *ev_file;
1225 struct devx_async_event_queue *ev_queue;
1226 unsigned long flags;
1227
1228 ev_file = container_of(fd_uobj, struct devx_async_cmd_event_file,
1229 uobj);
1230 ev_queue = &ev_file->ev_queue;
1231
1232 spin_lock_irqsave(&ev_queue->lock, flags);
1233 list_add_tail(&async_data->list, &ev_queue->event_list);
1234 spin_unlock_irqrestore(&ev_queue->lock, flags);
1235
1236 wake_up_interruptible(&ev_queue->poll_wait);
1237 fput(fd_uobj->object);
1238}
1239
1240#define MAX_ASYNC_BYTES_IN_USE (1024 * 1024) /* 1MB */
1241
1242static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY)(
1243 struct uverbs_attr_bundle *attrs)
1244{
1245 void *cmd_in = uverbs_attr_get_alloced_ptr(attrs,
1246 MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN);
1247 struct ib_uobject *uobj = uverbs_attr_get_uobject(
1248 attrs,
1249 MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_HANDLE);
1250 u16 cmd_out_len;
1251 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
1252 struct ib_uobject *fd_uobj;
1253 int err;
1254 int uid;
1255 struct mlx5_ib_dev *mdev = to_mdev(uobj->context->device);
1256 struct devx_async_cmd_event_file *ev_file;
1257 struct devx_async_data *async_data;
1258
1259 uid = devx_get_uid(c, cmd_in);
1260 if (uid < 0)
1261 return uid;
1262
1263 if (!devx_is_obj_query_cmd(cmd_in))
1264 return -EINVAL;
1265
1266 err = uverbs_get_const(&cmd_out_len, attrs,
1267 MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_OUT_LEN);
1268 if (err)
1269 return err;
1270
1271 if (!devx_is_valid_obj_id(uobj, cmd_in))
1272 return -EINVAL;
1273
1274 fd_uobj = uverbs_attr_get_uobject(attrs,
1275 MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_FD);
1276 if (IS_ERR(fd_uobj))
1277 return PTR_ERR(fd_uobj);
1278
1279 ev_file = container_of(fd_uobj, struct devx_async_cmd_event_file,
1280 uobj);
1281
1282 if (atomic_add_return(cmd_out_len, &ev_file->ev_queue.bytes_in_use) >
1283 MAX_ASYNC_BYTES_IN_USE) {
1284 atomic_sub(cmd_out_len, &ev_file->ev_queue.bytes_in_use);
1285 return -EAGAIN;
1286 }
1287
1288 async_data = kvzalloc(struct_size(async_data, hdr.out_data,
1289 cmd_out_len), GFP_KERNEL);
1290 if (!async_data) {
1291 err = -ENOMEM;
1292 goto sub_bytes;
1293 }
1294
1295 err = uverbs_copy_from(&async_data->hdr.wr_id, attrs,
1296 MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_WR_ID);
1297 if (err)
1298 goto free_async;
1299
1300 async_data->cmd_out_len = cmd_out_len;
1301 async_data->mdev = mdev;
1302 async_data->fd_uobj = fd_uobj;
1303
1304 get_file(fd_uobj->object);
1305 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid);
1306 err = mlx5_cmd_exec_cb(&ev_file->async_ctx, cmd_in,
1307 uverbs_attr_get_len(attrs,
1308 MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN),
1309 async_data->hdr.out_data,
1310 async_data->cmd_out_len,
1311 devx_query_callback, &async_data->cb_work);
1312
1313 if (err)
1314 goto cb_err;
1315
1316 return 0;
1317
1318cb_err:
1319 fput(fd_uobj->object);
1320free_async:
1321 kvfree(async_data);
1322sub_bytes:
1323 atomic_sub(cmd_out_len, &ev_file->ev_queue.bytes_in_use);
1324 return err;
1325}
1326
Yishai Hadasaeae9452018-06-17 13:00:04 +03001327static int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext,
1328 struct uverbs_attr_bundle *attrs,
1329 struct devx_umem *obj)
1330{
1331 u64 addr;
1332 size_t size;
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001333 u32 access;
Yishai Hadasaeae9452018-06-17 13:00:04 +03001334 int npages;
1335 int err;
1336 u32 page_mask;
1337
1338 if (uverbs_copy_from(&addr, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR) ||
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001339 uverbs_copy_from(&size, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_LEN))
Yishai Hadasaeae9452018-06-17 13:00:04 +03001340 return -EFAULT;
1341
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001342 err = uverbs_get_flags32(&access, attrs,
1343 MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS,
Yishai Hadas47f07f02018-12-05 15:50:21 +02001344 IB_ACCESS_LOCAL_WRITE |
1345 IB_ACCESS_REMOTE_WRITE |
1346 IB_ACCESS_REMOTE_READ);
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001347 if (err)
1348 return err;
1349
Yishai Hadasaeae9452018-06-17 13:00:04 +03001350 err = ib_check_mr_access(access);
1351 if (err)
1352 return err;
1353
1354 obj->umem = ib_umem_get(ucontext, addr, size, access, 0);
1355 if (IS_ERR(obj->umem))
1356 return PTR_ERR(obj->umem);
1357
1358 mlx5_ib_cont_pages(obj->umem, obj->umem->address,
1359 MLX5_MKEY_PAGE_SHIFT_MASK, &npages,
1360 &obj->page_shift, &obj->ncont, NULL);
1361
1362 if (!npages) {
1363 ib_umem_release(obj->umem);
1364 return -EINVAL;
1365 }
1366
1367 page_mask = (1 << obj->page_shift) - 1;
1368 obj->page_offset = obj->umem->address & page_mask;
1369
1370 return 0;
1371}
1372
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001373static int devx_umem_reg_cmd_alloc(struct uverbs_attr_bundle *attrs,
1374 struct devx_umem *obj,
Yishai Hadasaeae9452018-06-17 13:00:04 +03001375 struct devx_umem_reg_cmd *cmd)
1376{
1377 cmd->inlen = MLX5_ST_SZ_BYTES(create_umem_in) +
1378 (MLX5_ST_SZ_BYTES(mtt) * obj->ncont);
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001379 cmd->in = uverbs_zalloc(attrs, cmd->inlen);
1380 return PTR_ERR_OR_ZERO(cmd->in);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001381}
1382
1383static void devx_umem_reg_cmd_build(struct mlx5_ib_dev *dev,
1384 struct devx_umem *obj,
1385 struct devx_umem_reg_cmd *cmd)
1386{
1387 void *umem;
1388 __be64 *mtt;
1389
1390 umem = MLX5_ADDR_OF(create_umem_in, cmd->in, umem);
1391 mtt = (__be64 *)MLX5_ADDR_OF(umem, umem, mtt);
1392
Yishai Hadas6e3722b2018-12-19 16:28:15 +02001393 MLX5_SET(create_umem_in, cmd->in, opcode, MLX5_CMD_OP_CREATE_UMEM);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001394 MLX5_SET64(umem, umem, num_of_mtt, obj->ncont);
1395 MLX5_SET(umem, umem, log_page_size, obj->page_shift -
1396 MLX5_ADAPTER_PAGE_SHIFT);
1397 MLX5_SET(umem, umem, page_offset, obj->page_offset);
1398 mlx5_ib_populate_pas(dev, obj->umem, obj->page_shift, mtt,
1399 (obj->umem->writable ? MLX5_IB_MTT_WRITE : 0) |
1400 MLX5_IB_MTT_READ);
1401}
1402
Jason Gunthorpee83f0ec2018-07-25 21:40:18 -06001403static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_REG)(
Jason Gunthorpe15a1b4b2018-11-25 20:51:15 +02001404 struct uverbs_attr_bundle *attrs)
Yishai Hadasaeae9452018-06-17 13:00:04 +03001405{
Yishai Hadasaeae9452018-06-17 13:00:04 +03001406 struct devx_umem_reg_cmd cmd;
1407 struct devx_umem *obj;
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001408 struct ib_uobject *uobj = uverbs_attr_get_uobject(
1409 attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001410 u32 obj_id;
Jason Gunthorpec36ee462018-07-10 20:55:22 -06001411 struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
1412 struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001413 int err;
1414
1415 if (!c->devx_uid)
Yishai Hadas7e1335a2018-09-20 21:45:20 +03001416 return -EINVAL;
1417
Yishai Hadasaeae9452018-06-17 13:00:04 +03001418 obj = kzalloc(sizeof(struct devx_umem), GFP_KERNEL);
1419 if (!obj)
1420 return -ENOMEM;
1421
1422 err = devx_umem_get(dev, &c->ibucontext, attrs, obj);
1423 if (err)
1424 goto err_obj_free;
1425
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001426 err = devx_umem_reg_cmd_alloc(attrs, obj, &cmd);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001427 if (err)
1428 goto err_umem_release;
1429
1430 devx_umem_reg_cmd_build(dev, obj, &cmd);
1431
Yishai Hadas6e3722b2018-12-19 16:28:15 +02001432 MLX5_SET(create_umem_in, cmd.in, uid, c->devx_uid);
Yishai Hadasaeae9452018-06-17 13:00:04 +03001433 err = mlx5_cmd_exec(dev->mdev, cmd.in, cmd.inlen, cmd.out,
1434 sizeof(cmd.out));
1435 if (err)
Jason Gunthorpeb61815e2018-08-09 20:14:41 -06001436 goto err_umem_release;
Yishai Hadasaeae9452018-06-17 13:00:04 +03001437
1438 obj->mdev = dev->mdev;
1439 uobj->object = obj;
1440 devx_obj_build_destroy_cmd(cmd.in, cmd.out, obj->dinbox, &obj->dinlen, &obj_id);
1441 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, &obj_id, sizeof(obj_id));
1442 if (err)
1443 goto err_umem_destroy;
1444
Yishai Hadasaeae9452018-06-17 13:00:04 +03001445 return 0;
1446
1447err_umem_destroy:
1448 mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, cmd.out, sizeof(cmd.out));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001449err_umem_release:
1450 ib_umem_release(obj->umem);
1451err_obj_free:
1452 kfree(obj);
1453 return err;
1454}
1455
Yishai Hadasaeae9452018-06-17 13:00:04 +03001456static int devx_umem_cleanup(struct ib_uobject *uobject,
1457 enum rdma_remove_reason why)
1458{
1459 struct devx_umem *obj = uobject->object;
1460 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
1461 int err;
1462
1463 err = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
Yishai Hadas1c774832018-06-20 17:11:39 +03001464 if (ib_is_destroy_retryable(err, why, uobject))
Yishai Hadasaeae9452018-06-17 13:00:04 +03001465 return err;
1466
1467 ib_umem_release(obj->umem);
1468 kfree(obj);
1469 return 0;
1470}
1471
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001472static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf,
1473 size_t count, loff_t *pos)
1474{
1475 return -EINVAL;
1476}
1477
1478static int devx_async_cmd_event_close(struct inode *inode, struct file *filp)
1479{
Yishai Hadasa124edb2019-01-22 08:29:57 +02001480 struct ib_uobject *uobj = filp->private_data;
1481 struct devx_async_cmd_event_file *comp_ev_file = container_of(
1482 uobj, struct devx_async_cmd_event_file, uobj);
1483 struct devx_async_data *entry, *tmp;
1484
1485 spin_lock_irq(&comp_ev_file->ev_queue.lock);
1486 list_for_each_entry_safe(entry, tmp,
1487 &comp_ev_file->ev_queue.event_list, list)
1488 kvfree(entry);
1489 spin_unlock_irq(&comp_ev_file->ev_queue.lock);
1490
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001491 uverbs_close_fd(filp);
1492 return 0;
1493}
1494
1495static __poll_t devx_async_cmd_event_poll(struct file *filp,
1496 struct poll_table_struct *wait)
1497{
1498 return 0;
1499}
1500
1501const struct file_operations devx_async_cmd_event_fops = {
1502 .owner = THIS_MODULE,
1503 .read = devx_async_cmd_event_read,
1504 .poll = devx_async_cmd_event_poll,
1505 .release = devx_async_cmd_event_close,
1506 .llseek = no_llseek,
1507};
1508
1509static int devx_hot_unplug_async_cmd_event_file(struct ib_uobject *uobj,
1510 enum rdma_remove_reason why)
1511{
Yishai Hadasa124edb2019-01-22 08:29:57 +02001512 struct devx_async_cmd_event_file *comp_ev_file =
1513 container_of(uobj, struct devx_async_cmd_event_file,
1514 uobj);
1515
1516 mlx5_cmd_cleanup_async_ctx(&comp_ev_file->async_ctx);
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001517 return 0;
1518};
1519
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001520DECLARE_UVERBS_NAMED_METHOD(
1521 MLX5_IB_METHOD_DEVX_UMEM_REG,
1522 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE,
1523 MLX5_IB_OBJECT_DEVX_UMEM,
1524 UVERBS_ACCESS_NEW,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001525 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001526 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR,
1527 UVERBS_ATTR_TYPE(u64),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001528 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001529 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_LEN,
1530 UVERBS_ATTR_TYPE(u64),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001531 UA_MANDATORY),
Jason Gunthorpebccd0622018-07-26 16:37:14 -06001532 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS,
1533 enum ib_access_flags),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001534 UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID,
1535 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001536 UA_MANDATORY));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001537
Yishai Hadas528922a2018-07-08 13:24:39 +03001538DECLARE_UVERBS_NAMED_METHOD_DESTROY(
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001539 MLX5_IB_METHOD_DEVX_UMEM_DEREG,
1540 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE,
1541 MLX5_IB_OBJECT_DEVX_UMEM,
1542 UVERBS_ACCESS_DESTROY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001543 UA_MANDATORY));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001544
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001545DECLARE_UVERBS_NAMED_METHOD(
1546 MLX5_IB_METHOD_DEVX_QUERY_EQN,
1547 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC,
1548 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001549 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001550 UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN,
1551 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001552 UA_MANDATORY));
Yishai Hadasf6fe01b2018-06-17 13:00:05 +03001553
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001554DECLARE_UVERBS_NAMED_METHOD(
1555 MLX5_IB_METHOD_DEVX_QUERY_UAR,
1556 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX,
1557 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001558 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001559 UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX,
1560 UVERBS_ATTR_TYPE(u32),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001561 UA_MANDATORY));
Yishai Hadas7c043e92018-06-17 13:00:03 +03001562
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001563DECLARE_UVERBS_NAMED_METHOD(
1564 MLX5_IB_METHOD_DEVX_OTHER,
1565 UVERBS_ATTR_PTR_IN(
1566 MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
1567 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001568 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001569 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001570 UVERBS_ATTR_PTR_OUT(
1571 MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT,
1572 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001573 UA_MANDATORY));
Yishai Hadas8aa8c952018-06-17 13:00:00 +03001574
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001575DECLARE_UVERBS_NAMED_METHOD(
1576 MLX5_IB_METHOD_DEVX_OBJ_CREATE,
1577 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE,
1578 MLX5_IB_OBJECT_DEVX_OBJ,
1579 UVERBS_ACCESS_NEW,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001580 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001581 UVERBS_ATTR_PTR_IN(
1582 MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN,
1583 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001584 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001585 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001586 UVERBS_ATTR_PTR_OUT(
1587 MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT,
1588 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001589 UA_MANDATORY));
Yishai Hadas7efce362018-06-17 13:00:01 +03001590
Yishai Hadas528922a2018-07-08 13:24:39 +03001591DECLARE_UVERBS_NAMED_METHOD_DESTROY(
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001592 MLX5_IB_METHOD_DEVX_OBJ_DESTROY,
1593 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE,
1594 MLX5_IB_OBJECT_DEVX_OBJ,
1595 UVERBS_ACCESS_DESTROY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001596 UA_MANDATORY));
Yishai Hadas7efce362018-06-17 13:00:01 +03001597
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001598DECLARE_UVERBS_NAMED_METHOD(
1599 MLX5_IB_METHOD_DEVX_OBJ_MODIFY,
1600 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE,
Yishai Hadas34613eb2018-11-26 08:28:35 +02001601 UVERBS_IDR_ANY_OBJECT,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001602 UVERBS_ACCESS_WRITE,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001603 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001604 UVERBS_ATTR_PTR_IN(
1605 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN,
1606 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001607 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001608 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001609 UVERBS_ATTR_PTR_OUT(
1610 MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
1611 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001612 UA_MANDATORY));
Yishai Hadase662e142018-06-17 13:00:02 +03001613
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001614DECLARE_UVERBS_NAMED_METHOD(
1615 MLX5_IB_METHOD_DEVX_OBJ_QUERY,
1616 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE,
Yishai Hadas34613eb2018-11-26 08:28:35 +02001617 UVERBS_IDR_ANY_OBJECT,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001618 UVERBS_ACCESS_READ,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001619 UA_MANDATORY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001620 UVERBS_ATTR_PTR_IN(
1621 MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN,
1622 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001623 UA_MANDATORY,
Jason Gunthorpe83bb4442018-07-04 08:50:29 +03001624 UA_ALLOC_AND_COPY),
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001625 UVERBS_ATTR_PTR_OUT(
1626 MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
1627 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
Jason Gunthorpe540cd692018-07-04 08:50:30 +03001628 UA_MANDATORY));
Yishai Hadase662e142018-06-17 13:00:02 +03001629
Yishai Hadasa124edb2019-01-22 08:29:57 +02001630DECLARE_UVERBS_NAMED_METHOD(
1631 MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY,
1632 UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE,
1633 UVERBS_IDR_ANY_OBJECT,
1634 UVERBS_ACCESS_READ,
1635 UA_MANDATORY),
1636 UVERBS_ATTR_PTR_IN(
1637 MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN,
1638 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
1639 UA_MANDATORY,
1640 UA_ALLOC_AND_COPY),
1641 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_OUT_LEN,
1642 u16, UA_MANDATORY),
1643 UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_FD,
1644 MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD,
1645 UVERBS_ACCESS_READ,
1646 UA_MANDATORY),
1647 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_WR_ID,
1648 UVERBS_ATTR_TYPE(u64),
1649 UA_MANDATORY));
1650
Jason Gunthorpe6c61d2a2018-07-04 08:50:27 +03001651DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001652 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER),
1653 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR),
1654 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_EQN));
Yishai Hadas8aa8c952018-06-17 13:00:00 +03001655
Jason Gunthorpe6c61d2a2018-07-04 08:50:27 +03001656DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001657 UVERBS_TYPE_ALLOC_IDR(devx_obj_cleanup),
1658 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE),
1659 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY),
1660 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY),
Yishai Hadasa124edb2019-01-22 08:29:57 +02001661 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY),
1662 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY));
Yishai Hadas7efce362018-06-17 13:00:01 +03001663
Jason Gunthorpe6c61d2a2018-07-04 08:50:27 +03001664DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM,
Jason Gunthorpe9a119cd2018-07-04 08:50:28 +03001665 UVERBS_TYPE_ALLOC_IDR(devx_umem_cleanup),
1666 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG),
1667 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG));
Yishai Hadasaeae9452018-06-17 13:00:04 +03001668
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001669
1670DECLARE_UVERBS_NAMED_METHOD(
1671 MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC,
1672 UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_ASYNC_CMD_FD_ALLOC_HANDLE,
1673 MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD,
1674 UVERBS_ACCESS_NEW,
1675 UA_MANDATORY));
1676
1677DECLARE_UVERBS_NAMED_OBJECT(
1678 MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD,
1679 UVERBS_TYPE_ALLOC_FD(sizeof(struct devx_async_cmd_event_file),
1680 devx_hot_unplug_async_cmd_event_file,
1681 &devx_async_cmd_event_fops, "[devx_async_cmd]",
1682 O_RDONLY),
1683 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC));
1684
Jason Gunthorpe36e235c2018-11-12 22:59:53 +02001685static bool devx_is_supported(struct ib_device *device)
Yishai Hadasc59450c2018-06-17 13:00:06 +03001686{
Jason Gunthorpe36e235c2018-11-12 22:59:53 +02001687 struct mlx5_ib_dev *dev = to_mdev(device);
1688
Yishai Hadas6e3722b2018-12-19 16:28:15 +02001689 return !dev->rep && MLX5_CAP_GEN(dev->mdev, log_max_uctx);
Yishai Hadasc59450c2018-06-17 13:00:06 +03001690}
Jason Gunthorpe36e235c2018-11-12 22:59:53 +02001691
Jason Gunthorpe0cbf4322018-11-12 22:59:50 +02001692const struct uapi_definition mlx5_ib_devx_defs[] = {
Jason Gunthorpe36e235c2018-11-12 22:59:53 +02001693 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
1694 MLX5_IB_OBJECT_DEVX,
1695 UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)),
1696 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
1697 MLX5_IB_OBJECT_DEVX_OBJ,
1698 UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)),
1699 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
1700 MLX5_IB_OBJECT_DEVX_UMEM,
1701 UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)),
Yishai Hadas6bf8f222019-01-22 08:29:56 +02001702 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
1703 MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD,
1704 UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)),
Jason Gunthorpe0cbf4322018-11-12 22:59:50 +02001705 {},
1706};