devx.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
  2. /*
  3. * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
  4. */
  5. #include <rdma/ib_user_verbs.h>
  6. #include <rdma/ib_verbs.h>
  7. #include <rdma/uverbs_types.h>
  8. #include <rdma/uverbs_ioctl.h>
  9. #include <rdma/mlx5_user_ioctl_cmds.h>
  10. #include <rdma/ib_umem.h>
  11. #include <linux/mlx5/driver.h>
  12. #include <linux/mlx5/fs.h>
  13. #include "mlx5_ib.h"
  14. #define UVERBS_MODULE_NAME mlx5_ib
  15. #include <rdma/uverbs_named_ioctl.h>
  16. #define MLX5_MAX_DESTROY_INBOX_SIZE_DW MLX5_ST_SZ_DW(delete_fte_in)
  17. struct devx_obj {
  18. struct mlx5_core_dev *mdev;
  19. u32 obj_id;
  20. u32 dinlen; /* destroy inbox length */
  21. u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
  22. };
  23. static struct mlx5_ib_ucontext *devx_ufile2uctx(struct ib_uverbs_file *file)
  24. {
  25. return to_mucontext(ib_uverbs_get_ucontext(file));
  26. }
  27. int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, struct mlx5_ib_ucontext *context)
  28. {
  29. u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0};
  30. u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
  31. u64 general_obj_types;
  32. void *uctx;
  33. void *hdr;
  34. int err;
  35. uctx = MLX5_ADDR_OF(create_uctx_in, in, uctx);
  36. hdr = MLX5_ADDR_OF(create_uctx_in, in, hdr);
  37. general_obj_types = MLX5_CAP_GEN_64(dev->mdev, general_obj_types);
  38. if (!(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UCTX) ||
  39. !(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UMEM))
  40. return -EINVAL;
  41. if (!capable(CAP_NET_RAW))
  42. return -EPERM;
  43. MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
  44. MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, MLX5_OBJ_TYPE_UCTX);
  45. err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
  46. if (err)
  47. return err;
  48. context->devx_uid = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
  49. return 0;
  50. }
  51. void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev,
  52. struct mlx5_ib_ucontext *context)
  53. {
  54. u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
  55. u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
  56. MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
  57. MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_UCTX);
  58. MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, context->devx_uid);
  59. mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
  60. }
  61. static int devx_is_valid_obj_id(struct devx_obj *obj, const void *in)
  62. {
  63. u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
  64. u32 obj_id;
  65. switch (opcode) {
  66. case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
  67. case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
  68. obj_id = MLX5_GET(general_obj_in_cmd_hdr, in, obj_id);
  69. break;
  70. case MLX5_CMD_OP_QUERY_MKEY:
  71. obj_id = MLX5_GET(query_mkey_in, in, mkey_index);
  72. break;
  73. case MLX5_CMD_OP_QUERY_CQ:
  74. obj_id = MLX5_GET(query_cq_in, in, cqn);
  75. break;
  76. case MLX5_CMD_OP_MODIFY_CQ:
  77. obj_id = MLX5_GET(modify_cq_in, in, cqn);
  78. break;
  79. case MLX5_CMD_OP_QUERY_SQ:
  80. obj_id = MLX5_GET(query_sq_in, in, sqn);
  81. break;
  82. case MLX5_CMD_OP_MODIFY_SQ:
  83. obj_id = MLX5_GET(modify_sq_in, in, sqn);
  84. break;
  85. case MLX5_CMD_OP_QUERY_RQ:
  86. obj_id = MLX5_GET(query_rq_in, in, rqn);
  87. break;
  88. case MLX5_CMD_OP_MODIFY_RQ:
  89. obj_id = MLX5_GET(modify_rq_in, in, rqn);
  90. break;
  91. case MLX5_CMD_OP_QUERY_RMP:
  92. obj_id = MLX5_GET(query_rmp_in, in, rmpn);
  93. break;
  94. case MLX5_CMD_OP_MODIFY_RMP:
  95. obj_id = MLX5_GET(modify_rmp_in, in, rmpn);
  96. break;
  97. case MLX5_CMD_OP_QUERY_RQT:
  98. obj_id = MLX5_GET(query_rqt_in, in, rqtn);
  99. break;
  100. case MLX5_CMD_OP_MODIFY_RQT:
  101. obj_id = MLX5_GET(modify_rqt_in, in, rqtn);
  102. break;
  103. case MLX5_CMD_OP_QUERY_TIR:
  104. obj_id = MLX5_GET(query_tir_in, in, tirn);
  105. break;
  106. case MLX5_CMD_OP_MODIFY_TIR:
  107. obj_id = MLX5_GET(modify_tir_in, in, tirn);
  108. break;
  109. case MLX5_CMD_OP_QUERY_TIS:
  110. obj_id = MLX5_GET(query_tis_in, in, tisn);
  111. break;
  112. case MLX5_CMD_OP_MODIFY_TIS:
  113. obj_id = MLX5_GET(modify_tis_in, in, tisn);
  114. break;
  115. case MLX5_CMD_OP_QUERY_FLOW_TABLE:
  116. obj_id = MLX5_GET(query_flow_table_in, in, table_id);
  117. break;
  118. case MLX5_CMD_OP_MODIFY_FLOW_TABLE:
  119. obj_id = MLX5_GET(modify_flow_table_in, in, table_id);
  120. break;
  121. case MLX5_CMD_OP_QUERY_FLOW_GROUP:
  122. obj_id = MLX5_GET(query_flow_group_in, in, group_id);
  123. break;
  124. case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
  125. obj_id = MLX5_GET(query_fte_in, in, flow_index);
  126. break;
  127. case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
  128. obj_id = MLX5_GET(set_fte_in, in, flow_index);
  129. break;
  130. case MLX5_CMD_OP_QUERY_Q_COUNTER:
  131. obj_id = MLX5_GET(query_q_counter_in, in, counter_set_id);
  132. break;
  133. case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
  134. obj_id = MLX5_GET(query_flow_counter_in, in, flow_counter_id);
  135. break;
  136. case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT:
  137. obj_id = MLX5_GET(general_obj_in_cmd_hdr, in, obj_id);
  138. break;
  139. case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
  140. obj_id = MLX5_GET(query_scheduling_element_in, in,
  141. scheduling_element_id);
  142. break;
  143. case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT:
  144. obj_id = MLX5_GET(modify_scheduling_element_in, in,
  145. scheduling_element_id);
  146. break;
  147. case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
  148. obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port);
  149. break;
  150. case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY:
  151. obj_id = MLX5_GET(query_l2_table_entry_in, in, table_index);
  152. break;
  153. case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
  154. obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index);
  155. break;
  156. case MLX5_CMD_OP_QUERY_QP:
  157. obj_id = MLX5_GET(query_qp_in, in, qpn);
  158. break;
  159. case MLX5_CMD_OP_RST2INIT_QP:
  160. obj_id = MLX5_GET(rst2init_qp_in, in, qpn);
  161. break;
  162. case MLX5_CMD_OP_INIT2RTR_QP:
  163. obj_id = MLX5_GET(init2rtr_qp_in, in, qpn);
  164. break;
  165. case MLX5_CMD_OP_RTR2RTS_QP:
  166. obj_id = MLX5_GET(rtr2rts_qp_in, in, qpn);
  167. break;
  168. case MLX5_CMD_OP_RTS2RTS_QP:
  169. obj_id = MLX5_GET(rts2rts_qp_in, in, qpn);
  170. break;
  171. case MLX5_CMD_OP_SQERR2RTS_QP:
  172. obj_id = MLX5_GET(sqerr2rts_qp_in, in, qpn);
  173. break;
  174. case MLX5_CMD_OP_2ERR_QP:
  175. obj_id = MLX5_GET(qp_2err_in, in, qpn);
  176. break;
  177. case MLX5_CMD_OP_2RST_QP:
  178. obj_id = MLX5_GET(qp_2rst_in, in, qpn);
  179. break;
  180. case MLX5_CMD_OP_QUERY_DCT:
  181. obj_id = MLX5_GET(query_dct_in, in, dctn);
  182. break;
  183. case MLX5_CMD_OP_QUERY_XRQ:
  184. obj_id = MLX5_GET(query_xrq_in, in, xrqn);
  185. break;
  186. case MLX5_CMD_OP_QUERY_XRC_SRQ:
  187. obj_id = MLX5_GET(query_xrc_srq_in, in, xrc_srqn);
  188. break;
  189. case MLX5_CMD_OP_ARM_XRC_SRQ:
  190. obj_id = MLX5_GET(arm_xrc_srq_in, in, xrc_srqn);
  191. break;
  192. case MLX5_CMD_OP_QUERY_SRQ:
  193. obj_id = MLX5_GET(query_srq_in, in, srqn);
  194. break;
  195. case MLX5_CMD_OP_ARM_RQ:
  196. obj_id = MLX5_GET(arm_rq_in, in, srq_number);
  197. break;
  198. case MLX5_CMD_OP_DRAIN_DCT:
  199. case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
  200. obj_id = MLX5_GET(drain_dct_in, in, dctn);
  201. break;
  202. case MLX5_CMD_OP_ARM_XRQ:
  203. obj_id = MLX5_GET(arm_xrq_in, in, xrqn);
  204. break;
  205. default:
  206. return false;
  207. }
  208. if (obj_id == obj->obj_id)
  209. return true;
  210. return false;
  211. }
  212. static bool devx_is_obj_create_cmd(const void *in)
  213. {
  214. u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
  215. switch (opcode) {
  216. case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
  217. case MLX5_CMD_OP_CREATE_MKEY:
  218. case MLX5_CMD_OP_CREATE_CQ:
  219. case MLX5_CMD_OP_ALLOC_PD:
  220. case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN:
  221. case MLX5_CMD_OP_CREATE_RMP:
  222. case MLX5_CMD_OP_CREATE_SQ:
  223. case MLX5_CMD_OP_CREATE_RQ:
  224. case MLX5_CMD_OP_CREATE_RQT:
  225. case MLX5_CMD_OP_CREATE_TIR:
  226. case MLX5_CMD_OP_CREATE_TIS:
  227. case MLX5_CMD_OP_ALLOC_Q_COUNTER:
  228. case MLX5_CMD_OP_CREATE_FLOW_TABLE:
  229. case MLX5_CMD_OP_CREATE_FLOW_GROUP:
  230. case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
  231. case MLX5_CMD_OP_ALLOC_ENCAP_HEADER:
  232. case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
  233. case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
  234. case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
  235. case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
  236. case MLX5_CMD_OP_CREATE_QP:
  237. case MLX5_CMD_OP_CREATE_SRQ:
  238. case MLX5_CMD_OP_CREATE_XRC_SRQ:
  239. case MLX5_CMD_OP_CREATE_DCT:
  240. case MLX5_CMD_OP_CREATE_XRQ:
  241. case MLX5_CMD_OP_ATTACH_TO_MCG:
  242. case MLX5_CMD_OP_ALLOC_XRCD:
  243. return true;
  244. case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
  245. {
  246. u16 op_mod = MLX5_GET(set_fte_in, in, op_mod);
  247. if (op_mod == 0)
  248. return true;
  249. return false;
  250. }
  251. default:
  252. return false;
  253. }
  254. }
  255. static bool devx_is_obj_modify_cmd(const void *in)
  256. {
  257. u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
  258. switch (opcode) {
  259. case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
  260. case MLX5_CMD_OP_MODIFY_CQ:
  261. case MLX5_CMD_OP_MODIFY_RMP:
  262. case MLX5_CMD_OP_MODIFY_SQ:
  263. case MLX5_CMD_OP_MODIFY_RQ:
  264. case MLX5_CMD_OP_MODIFY_RQT:
  265. case MLX5_CMD_OP_MODIFY_TIR:
  266. case MLX5_CMD_OP_MODIFY_TIS:
  267. case MLX5_CMD_OP_MODIFY_FLOW_TABLE:
  268. case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT:
  269. case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
  270. case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
  271. case MLX5_CMD_OP_RST2INIT_QP:
  272. case MLX5_CMD_OP_INIT2RTR_QP:
  273. case MLX5_CMD_OP_RTR2RTS_QP:
  274. case MLX5_CMD_OP_RTS2RTS_QP:
  275. case MLX5_CMD_OP_SQERR2RTS_QP:
  276. case MLX5_CMD_OP_2ERR_QP:
  277. case MLX5_CMD_OP_2RST_QP:
  278. case MLX5_CMD_OP_ARM_XRC_SRQ:
  279. case MLX5_CMD_OP_ARM_RQ:
  280. case MLX5_CMD_OP_DRAIN_DCT:
  281. case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
  282. case MLX5_CMD_OP_ARM_XRQ:
  283. return true;
  284. case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
  285. {
  286. u16 op_mod = MLX5_GET(set_fte_in, in, op_mod);
  287. if (op_mod == 1)
  288. return true;
  289. return false;
  290. }
  291. default:
  292. return false;
  293. }
  294. }
  295. static bool devx_is_obj_query_cmd(const void *in)
  296. {
  297. u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
  298. switch (opcode) {
  299. case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
  300. case MLX5_CMD_OP_QUERY_MKEY:
  301. case MLX5_CMD_OP_QUERY_CQ:
  302. case MLX5_CMD_OP_QUERY_RMP:
  303. case MLX5_CMD_OP_QUERY_SQ:
  304. case MLX5_CMD_OP_QUERY_RQ:
  305. case MLX5_CMD_OP_QUERY_RQT:
  306. case MLX5_CMD_OP_QUERY_TIR:
  307. case MLX5_CMD_OP_QUERY_TIS:
  308. case MLX5_CMD_OP_QUERY_Q_COUNTER:
  309. case MLX5_CMD_OP_QUERY_FLOW_TABLE:
  310. case MLX5_CMD_OP_QUERY_FLOW_GROUP:
  311. case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
  312. case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
  313. case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT:
  314. case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
  315. case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY:
  316. case MLX5_CMD_OP_QUERY_QP:
  317. case MLX5_CMD_OP_QUERY_SRQ:
  318. case MLX5_CMD_OP_QUERY_XRC_SRQ:
  319. case MLX5_CMD_OP_QUERY_DCT:
  320. case MLX5_CMD_OP_QUERY_XRQ:
  321. return true;
  322. default:
  323. return false;
  324. }
  325. }
  326. static bool devx_is_general_cmd(void *in)
  327. {
  328. u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode);
  329. switch (opcode) {
  330. case MLX5_CMD_OP_QUERY_HCA_CAP:
  331. case MLX5_CMD_OP_QUERY_VPORT_STATE:
  332. case MLX5_CMD_OP_QUERY_ADAPTER:
  333. case MLX5_CMD_OP_QUERY_ISSI:
  334. case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT:
  335. case MLX5_CMD_OP_QUERY_ROCE_ADDRESS:
  336. case MLX5_CMD_OP_QUERY_VNIC_ENV:
  337. case MLX5_CMD_OP_QUERY_VPORT_COUNTER:
  338. case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG:
  339. case MLX5_CMD_OP_NOP:
  340. case MLX5_CMD_OP_QUERY_CONG_STATUS:
  341. case MLX5_CMD_OP_QUERY_CONG_PARAMS:
  342. case MLX5_CMD_OP_QUERY_CONG_STATISTICS:
  343. return true;
  344. default:
  345. return false;
  346. }
  347. }
  348. static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)(struct ib_device *ib_dev,
  349. struct ib_uverbs_file *file,
  350. struct uverbs_attr_bundle *attrs)
  351. {
  352. struct mlx5_ib_ucontext *c = devx_ufile2uctx(file);
  353. struct mlx5_ib_dev *dev = to_mdev(ib_dev);
  354. void *cmd_in = uverbs_attr_get_alloced_ptr(
  355. attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN);
  356. int cmd_out_len = uverbs_attr_get_len(attrs,
  357. MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT);
  358. void *cmd_out;
  359. int err;
  360. if (!c->devx_uid)
  361. return -EPERM;
  362. /* Only white list of some general HCA commands are allowed for this method. */
  363. if (!devx_is_general_cmd(cmd_in))
  364. return -EINVAL;
  365. cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL);
  366. if (!cmd_out)
  367. return -ENOMEM;
  368. MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid);
  369. err = mlx5_cmd_exec(dev->mdev, cmd_in,
  370. uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN),
  371. cmd_out, cmd_out_len);
  372. if (err)
  373. goto other_cmd_free;
  374. err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out, cmd_out_len);
  375. other_cmd_free:
  376. kvfree(cmd_out);
  377. return err;
  378. }
  379. static void devx_obj_build_destroy_cmd(void *in, void *out, void *din,
  380. u32 *dinlen,
  381. u32 *obj_id)
  382. {
  383. u16 obj_type = MLX5_GET(general_obj_in_cmd_hdr, in, obj_type);
  384. u16 uid = MLX5_GET(general_obj_in_cmd_hdr, in, uid);
  385. *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
  386. *dinlen = MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr);
  387. MLX5_SET(general_obj_in_cmd_hdr, din, obj_id, *obj_id);
  388. MLX5_SET(general_obj_in_cmd_hdr, din, uid, uid);
  389. switch (MLX5_GET(general_obj_in_cmd_hdr, in, opcode)) {
  390. case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
  391. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
  392. MLX5_SET(general_obj_in_cmd_hdr, din, obj_type, obj_type);
  393. break;
  394. case MLX5_CMD_OP_CREATE_MKEY:
  395. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_MKEY);
  396. break;
  397. case MLX5_CMD_OP_CREATE_CQ:
  398. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_CQ);
  399. break;
  400. case MLX5_CMD_OP_ALLOC_PD:
  401. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_PD);
  402. break;
  403. case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN:
  404. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  405. MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN);
  406. break;
  407. case MLX5_CMD_OP_CREATE_RMP:
  408. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RMP);
  409. break;
  410. case MLX5_CMD_OP_CREATE_SQ:
  411. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SQ);
  412. break;
  413. case MLX5_CMD_OP_CREATE_RQ:
  414. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQ);
  415. break;
  416. case MLX5_CMD_OP_CREATE_RQT:
  417. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT);
  418. break;
  419. case MLX5_CMD_OP_CREATE_TIR:
  420. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIR);
  421. break;
  422. case MLX5_CMD_OP_CREATE_TIS:
  423. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS);
  424. break;
  425. case MLX5_CMD_OP_ALLOC_Q_COUNTER:
  426. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  427. MLX5_CMD_OP_DEALLOC_Q_COUNTER);
  428. break;
  429. case MLX5_CMD_OP_CREATE_FLOW_TABLE:
  430. *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_table_in);
  431. *obj_id = MLX5_GET(create_flow_table_out, out, table_id);
  432. MLX5_SET(destroy_flow_table_in, din, other_vport,
  433. MLX5_GET(create_flow_table_in, in, other_vport));
  434. MLX5_SET(destroy_flow_table_in, din, vport_number,
  435. MLX5_GET(create_flow_table_in, in, vport_number));
  436. MLX5_SET(destroy_flow_table_in, din, table_type,
  437. MLX5_GET(create_flow_table_in, in, table_type));
  438. MLX5_SET(destroy_flow_table_in, din, table_id, *obj_id);
  439. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  440. MLX5_CMD_OP_DESTROY_FLOW_TABLE);
  441. break;
  442. case MLX5_CMD_OP_CREATE_FLOW_GROUP:
  443. *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_group_in);
  444. *obj_id = MLX5_GET(create_flow_group_out, out, group_id);
  445. MLX5_SET(destroy_flow_group_in, din, other_vport,
  446. MLX5_GET(create_flow_group_in, in, other_vport));
  447. MLX5_SET(destroy_flow_group_in, din, vport_number,
  448. MLX5_GET(create_flow_group_in, in, vport_number));
  449. MLX5_SET(destroy_flow_group_in, din, table_type,
  450. MLX5_GET(create_flow_group_in, in, table_type));
  451. MLX5_SET(destroy_flow_group_in, din, table_id,
  452. MLX5_GET(create_flow_group_in, in, table_id));
  453. MLX5_SET(destroy_flow_group_in, din, group_id, *obj_id);
  454. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  455. MLX5_CMD_OP_DESTROY_FLOW_GROUP);
  456. break;
  457. case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
  458. *dinlen = MLX5_ST_SZ_BYTES(delete_fte_in);
  459. *obj_id = MLX5_GET(set_fte_in, in, flow_index);
  460. MLX5_SET(delete_fte_in, din, other_vport,
  461. MLX5_GET(set_fte_in, in, other_vport));
  462. MLX5_SET(delete_fte_in, din, vport_number,
  463. MLX5_GET(set_fte_in, in, vport_number));
  464. MLX5_SET(delete_fte_in, din, table_type,
  465. MLX5_GET(set_fte_in, in, table_type));
  466. MLX5_SET(delete_fte_in, din, table_id,
  467. MLX5_GET(set_fte_in, in, table_id));
  468. MLX5_SET(delete_fte_in, din, flow_index, *obj_id);
  469. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  470. MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY);
  471. break;
  472. case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
  473. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  474. MLX5_CMD_OP_DEALLOC_FLOW_COUNTER);
  475. break;
  476. case MLX5_CMD_OP_ALLOC_ENCAP_HEADER:
  477. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  478. MLX5_CMD_OP_DEALLOC_ENCAP_HEADER);
  479. break;
  480. case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
  481. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  482. MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT);
  483. break;
  484. case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
  485. *dinlen = MLX5_ST_SZ_BYTES(destroy_scheduling_element_in);
  486. *obj_id = MLX5_GET(create_scheduling_element_out, out,
  487. scheduling_element_id);
  488. MLX5_SET(destroy_scheduling_element_in, din,
  489. scheduling_hierarchy,
  490. MLX5_GET(create_scheduling_element_in, in,
  491. scheduling_hierarchy));
  492. MLX5_SET(destroy_scheduling_element_in, din,
  493. scheduling_element_id, *obj_id);
  494. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  495. MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT);
  496. break;
  497. case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
  498. *dinlen = MLX5_ST_SZ_BYTES(delete_vxlan_udp_dport_in);
  499. *obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port);
  500. MLX5_SET(delete_vxlan_udp_dport_in, din, vxlan_udp_port, *obj_id);
  501. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  502. MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
  503. break;
  504. case MLX5_CMD_OP_SET_L2_TABLE_ENTRY:
  505. *dinlen = MLX5_ST_SZ_BYTES(delete_l2_table_entry_in);
  506. *obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index);
  507. MLX5_SET(delete_l2_table_entry_in, din, table_index, *obj_id);
  508. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  509. MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY);
  510. break;
  511. case MLX5_CMD_OP_CREATE_QP:
  512. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_QP);
  513. break;
  514. case MLX5_CMD_OP_CREATE_SRQ:
  515. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SRQ);
  516. break;
  517. case MLX5_CMD_OP_CREATE_XRC_SRQ:
  518. MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
  519. MLX5_CMD_OP_DESTROY_XRC_SRQ);
  520. break;
  521. case MLX5_CMD_OP_CREATE_DCT:
  522. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_DCT);
  523. break;
  524. case MLX5_CMD_OP_CREATE_XRQ:
  525. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_XRQ);
  526. break;
  527. case MLX5_CMD_OP_ATTACH_TO_MCG:
  528. *dinlen = MLX5_ST_SZ_BYTES(detach_from_mcg_in);
  529. MLX5_SET(detach_from_mcg_in, din, qpn,
  530. MLX5_GET(attach_to_mcg_in, in, qpn));
  531. memcpy(MLX5_ADDR_OF(detach_from_mcg_in, din, multicast_gid),
  532. MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid),
  533. MLX5_FLD_SZ_BYTES(attach_to_mcg_in, multicast_gid));
  534. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DETACH_FROM_MCG);
  535. break;
  536. case MLX5_CMD_OP_ALLOC_XRCD:
  537. MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
  538. break;
  539. default:
  540. /* The entry must match to one of the devx_is_obj_create_cmd */
  541. WARN_ON(true);
  542. break;
  543. }
  544. }
  545. static int devx_obj_cleanup(struct ib_uobject *uobject,
  546. enum rdma_remove_reason why)
  547. {
  548. u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
  549. struct devx_obj *obj = uobject->object;
  550. int ret;
  551. ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
  552. if (ret && why == RDMA_REMOVE_DESTROY)
  553. return ret;
  554. kfree(obj);
  555. return ret;
  556. }
  557. static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_DESTROY)(struct ib_device *ib_dev,
  558. struct ib_uverbs_file *file,
  559. struct uverbs_attr_bundle *attrs)
  560. {
  561. return 0;
  562. }
  563. static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(struct ib_device *ib_dev,
  564. struct ib_uverbs_file *file,
  565. struct uverbs_attr_bundle *attrs)
  566. {
  567. struct mlx5_ib_ucontext *c = devx_ufile2uctx(file);
  568. struct mlx5_ib_dev *dev = to_mdev(ib_dev);
  569. void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN);
  570. int cmd_out_len = uverbs_attr_get_len(attrs,
  571. MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT);
  572. void *cmd_out;
  573. struct ib_uobject *uobj;
  574. struct devx_obj *obj;
  575. int err;
  576. if (!c->devx_uid)
  577. return -EPERM;
  578. if (!devx_is_obj_create_cmd(cmd_in))
  579. return -EINVAL;
  580. obj = kzalloc(sizeof(struct devx_obj), GFP_KERNEL);
  581. if (!obj)
  582. return -ENOMEM;
  583. cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL);
  584. if (!cmd_out) {
  585. err = -ENOMEM;
  586. goto obj_free;
  587. }
  588. MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid);
  589. err = mlx5_cmd_exec(dev->mdev, cmd_in,
  590. uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN),
  591. cmd_out, cmd_out_len);
  592. if (err)
  593. goto cmd_free;
  594. uobj = uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE);
  595. uobj->object = obj;
  596. obj->mdev = dev->mdev;
  597. devx_obj_build_destroy_cmd(cmd_in, cmd_out, obj->dinbox, &obj->dinlen, &obj->obj_id);
  598. WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32));
  599. err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len);
  600. if (err)
  601. goto cmd_free;
  602. kvfree(cmd_out);
  603. return 0;
  604. cmd_free:
  605. kvfree(cmd_out);
  606. obj_free:
  607. kfree(obj);
  608. return err;
  609. }
  610. static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MODIFY)(struct ib_device *ib_dev,
  611. struct ib_uverbs_file *file,
  612. struct uverbs_attr_bundle *attrs)
  613. {
  614. struct mlx5_ib_ucontext *c = devx_ufile2uctx(file);
  615. struct mlx5_ib_dev *dev = to_mdev(ib_dev);
  616. void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN);
  617. int cmd_out_len = uverbs_attr_get_len(attrs,
  618. MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT);
  619. struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
  620. MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE);
  621. void *cmd_out;
  622. int err;
  623. if (!c->devx_uid)
  624. return -EPERM;
  625. if (!devx_is_obj_modify_cmd(cmd_in))
  626. return -EINVAL;
  627. if (!devx_is_valid_obj_id(uobj->object, cmd_in))
  628. return -EINVAL;
  629. cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL);
  630. if (!cmd_out)
  631. return -ENOMEM;
  632. MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid);
  633. err = mlx5_cmd_exec(dev->mdev, cmd_in,
  634. uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN),
  635. cmd_out, cmd_out_len);
  636. if (err)
  637. goto other_cmd_free;
  638. err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
  639. cmd_out, cmd_out_len);
  640. other_cmd_free:
  641. kvfree(cmd_out);
  642. return err;
  643. }
  644. static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)(struct ib_device *ib_dev,
  645. struct ib_uverbs_file *file,
  646. struct uverbs_attr_bundle *attrs)
  647. {
  648. struct mlx5_ib_ucontext *c = devx_ufile2uctx(file);
  649. struct mlx5_ib_dev *dev = to_mdev(ib_dev);
  650. void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN);
  651. int cmd_out_len = uverbs_attr_get_len(attrs,
  652. MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT);
  653. struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
  654. MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE);
  655. void *cmd_out;
  656. int err;
  657. if (!c->devx_uid)
  658. return -EPERM;
  659. if (!devx_is_obj_query_cmd(cmd_in))
  660. return -EINVAL;
  661. if (!devx_is_valid_obj_id(uobj->object, cmd_in))
  662. return -EINVAL;
  663. cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL);
  664. if (!cmd_out)
  665. return -ENOMEM;
  666. MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid);
  667. err = mlx5_cmd_exec(dev->mdev, cmd_in,
  668. uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN),
  669. cmd_out, cmd_out_len);
  670. if (err)
  671. goto other_cmd_free;
  672. err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, cmd_out, cmd_out_len);
  673. other_cmd_free:
  674. kvfree(cmd_out);
  675. return err;
  676. }
  677. static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OTHER,
  678. &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
  679. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
  680. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  681. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
  682. UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
  683. &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT,
  684. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
  685. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  686. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))
  687. );
  688. static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE,
  689. &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE,
  690. MLX5_IB_OBJECT_DEVX_OBJ,
  691. UVERBS_ACCESS_NEW,
  692. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
  693. &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN,
  694. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
  695. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  696. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
  697. UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
  698. &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT,
  699. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
  700. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  701. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
  702. static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY,
  703. &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE,
  704. MLX5_IB_OBJECT_DEVX_OBJ,
  705. UVERBS_ACCESS_DESTROY,
  706. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
  707. static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY,
  708. &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE,
  709. MLX5_IB_OBJECT_DEVX_OBJ,
  710. UVERBS_ACCESS_WRITE,
  711. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
  712. &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN,
  713. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
  714. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  715. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
  716. UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
  717. &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
  718. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
  719. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  720. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
  721. static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY,
  722. &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE,
  723. MLX5_IB_OBJECT_DEVX_OBJ,
  724. UVERBS_ACCESS_READ,
  725. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
  726. &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN,
  727. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
  728. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  729. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
  730. UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
  731. &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
  732. UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
  733. UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
  734. UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
  735. static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX,
  736. &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER));
  737. static DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ,
  738. &UVERBS_TYPE_ALLOC_IDR(0, devx_obj_cleanup),
  739. &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE),
  740. &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY),
  741. &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY),
  742. &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY));
  743. static DECLARE_UVERBS_OBJECT_TREE(devx_objects,
  744. &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX),
  745. &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ));