1a8b92ca1SYishai Hadas // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2a8b92ca1SYishai Hadas /* 3a8b92ca1SYishai Hadas * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. 4a8b92ca1SYishai Hadas */ 5a8b92ca1SYishai Hadas 6a8b92ca1SYishai Hadas #include <rdma/ib_user_verbs.h> 7a8b92ca1SYishai Hadas #include <rdma/ib_verbs.h> 8a8b92ca1SYishai Hadas #include <rdma/uverbs_types.h> 9a8b92ca1SYishai Hadas #include <rdma/uverbs_ioctl.h> 10a8b92ca1SYishai Hadas #include <rdma/mlx5_user_ioctl_cmds.h> 11a8b92ca1SYishai Hadas #include <rdma/ib_umem.h> 12a8b92ca1SYishai Hadas #include <linux/mlx5/driver.h> 13a8b92ca1SYishai Hadas #include <linux/mlx5/fs.h> 14a8b92ca1SYishai Hadas #include "mlx5_ib.h" 15a8b92ca1SYishai Hadas 168aa8c95cSYishai Hadas #define UVERBS_MODULE_NAME mlx5_ib 178aa8c95cSYishai Hadas #include <rdma/uverbs_named_ioctl.h> 188aa8c95cSYishai Hadas 197efce369SYishai Hadas #define MLX5_MAX_DESTROY_INBOX_SIZE_DW MLX5_ST_SZ_DW(delete_fte_in) 207efce369SYishai Hadas struct devx_obj { 217efce369SYishai Hadas struct mlx5_core_dev *mdev; 227efce369SYishai Hadas u32 obj_id; 237efce369SYishai Hadas u32 dinlen; /* destroy inbox length */ 247efce369SYishai Hadas u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW]; 257efce369SYishai Hadas }; 267efce369SYishai Hadas 27aeae9457SYishai Hadas struct devx_umem { 28aeae9457SYishai Hadas struct mlx5_core_dev *mdev; 29aeae9457SYishai Hadas struct ib_umem *umem; 30aeae9457SYishai Hadas u32 page_offset; 31aeae9457SYishai Hadas int page_shift; 32aeae9457SYishai Hadas int ncont; 33aeae9457SYishai Hadas u32 dinlen; 34aeae9457SYishai Hadas u32 dinbox[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)]; 35aeae9457SYishai Hadas }; 36aeae9457SYishai Hadas 37aeae9457SYishai Hadas struct devx_umem_reg_cmd { 38aeae9457SYishai Hadas void *in; 39aeae9457SYishai Hadas u32 inlen; 40aeae9457SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 41aeae9457SYishai Hadas }; 42aeae9457SYishai Hadas 438aa8c95cSYishai Hadas static struct mlx5_ib_ucontext *devx_ufile2uctx(struct ib_uverbs_file *file) 448aa8c95cSYishai Hadas { 458aa8c95cSYishai Hadas return to_mucontext(ib_uverbs_get_ucontext(file)); 468aa8c95cSYishai Hadas } 478aa8c95cSYishai Hadas 48a8b92ca1SYishai Hadas int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, struct mlx5_ib_ucontext *context) 49a8b92ca1SYishai Hadas { 50a8b92ca1SYishai Hadas u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0}; 51a8b92ca1SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 52a8b92ca1SYishai Hadas u64 general_obj_types; 53a8b92ca1SYishai Hadas void *hdr; 54a8b92ca1SYishai Hadas int err; 55a8b92ca1SYishai Hadas 56a8b92ca1SYishai Hadas hdr = MLX5_ADDR_OF(create_uctx_in, in, hdr); 57a8b92ca1SYishai Hadas 58a8b92ca1SYishai Hadas general_obj_types = MLX5_CAP_GEN_64(dev->mdev, general_obj_types); 59a8b92ca1SYishai Hadas if (!(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UCTX) || 60a8b92ca1SYishai Hadas !(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UMEM)) 61a8b92ca1SYishai Hadas return -EINVAL; 62a8b92ca1SYishai Hadas 63a8b92ca1SYishai Hadas if (!capable(CAP_NET_RAW)) 64a8b92ca1SYishai Hadas return -EPERM; 65a8b92ca1SYishai Hadas 66a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 67a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, MLX5_OBJ_TYPE_UCTX); 68a8b92ca1SYishai Hadas 69a8b92ca1SYishai Hadas err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 70a8b92ca1SYishai Hadas if (err) 71a8b92ca1SYishai Hadas return err; 72a8b92ca1SYishai Hadas 73a8b92ca1SYishai Hadas context->devx_uid = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 74a8b92ca1SYishai Hadas return 0; 75a8b92ca1SYishai Hadas } 76a8b92ca1SYishai Hadas 77a8b92ca1SYishai Hadas void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, 78a8b92ca1SYishai Hadas struct mlx5_ib_ucontext *context) 79a8b92ca1SYishai Hadas { 80a8b92ca1SYishai Hadas u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0}; 81a8b92ca1SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 82a8b92ca1SYishai Hadas 83a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 84a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_UCTX); 85a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, context->devx_uid); 86a8b92ca1SYishai Hadas 87a8b92ca1SYishai Hadas mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 88a8b92ca1SYishai Hadas } 898aa8c95cSYishai Hadas 9032269441SYishai Hadas bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type) 9132269441SYishai Hadas { 9232269441SYishai Hadas struct devx_obj *devx_obj = obj; 9332269441SYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode); 9432269441SYishai Hadas 9532269441SYishai Hadas switch (opcode) { 9632269441SYishai Hadas case MLX5_CMD_OP_DESTROY_TIR: 9732269441SYishai Hadas *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR; 9832269441SYishai Hadas *dest_id = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, 9932269441SYishai Hadas obj_id); 10032269441SYishai Hadas return true; 10132269441SYishai Hadas 10232269441SYishai Hadas case MLX5_CMD_OP_DESTROY_FLOW_TABLE: 10332269441SYishai Hadas *dest_type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 10432269441SYishai Hadas *dest_id = MLX5_GET(destroy_flow_table_in, devx_obj->dinbox, 10532269441SYishai Hadas table_id); 10632269441SYishai Hadas return true; 10732269441SYishai Hadas default: 10832269441SYishai Hadas return false; 10932269441SYishai Hadas } 11032269441SYishai Hadas } 11132269441SYishai Hadas 112e662e14dSYishai Hadas static int devx_is_valid_obj_id(struct devx_obj *obj, const void *in) 113e662e14dSYishai Hadas { 114e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 115e662e14dSYishai Hadas u32 obj_id; 116e662e14dSYishai Hadas 117e662e14dSYishai Hadas switch (opcode) { 118e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 119e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 120e662e14dSYishai Hadas obj_id = MLX5_GET(general_obj_in_cmd_hdr, in, obj_id); 121e662e14dSYishai Hadas break; 122e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MKEY: 123e662e14dSYishai Hadas obj_id = MLX5_GET(query_mkey_in, in, mkey_index); 124e662e14dSYishai Hadas break; 125e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_CQ: 126e662e14dSYishai Hadas obj_id = MLX5_GET(query_cq_in, in, cqn); 127e662e14dSYishai Hadas break; 128e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_CQ: 129e662e14dSYishai Hadas obj_id = MLX5_GET(modify_cq_in, in, cqn); 130e662e14dSYishai Hadas break; 131e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SQ: 132e662e14dSYishai Hadas obj_id = MLX5_GET(query_sq_in, in, sqn); 133e662e14dSYishai Hadas break; 134e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SQ: 135e662e14dSYishai Hadas obj_id = MLX5_GET(modify_sq_in, in, sqn); 136e662e14dSYishai Hadas break; 137e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQ: 138e662e14dSYishai Hadas obj_id = MLX5_GET(query_rq_in, in, rqn); 139e662e14dSYishai Hadas break; 140e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQ: 141e662e14dSYishai Hadas obj_id = MLX5_GET(modify_rq_in, in, rqn); 142e662e14dSYishai Hadas break; 143e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RMP: 144e662e14dSYishai Hadas obj_id = MLX5_GET(query_rmp_in, in, rmpn); 145e662e14dSYishai Hadas break; 146e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RMP: 147e662e14dSYishai Hadas obj_id = MLX5_GET(modify_rmp_in, in, rmpn); 148e662e14dSYishai Hadas break; 149e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQT: 150e662e14dSYishai Hadas obj_id = MLX5_GET(query_rqt_in, in, rqtn); 151e662e14dSYishai Hadas break; 152e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQT: 153e662e14dSYishai Hadas obj_id = MLX5_GET(modify_rqt_in, in, rqtn); 154e662e14dSYishai Hadas break; 155e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIR: 156e662e14dSYishai Hadas obj_id = MLX5_GET(query_tir_in, in, tirn); 157e662e14dSYishai Hadas break; 158e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIR: 159e662e14dSYishai Hadas obj_id = MLX5_GET(modify_tir_in, in, tirn); 160e662e14dSYishai Hadas break; 161e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIS: 162e662e14dSYishai Hadas obj_id = MLX5_GET(query_tis_in, in, tisn); 163e662e14dSYishai Hadas break; 164e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIS: 165e662e14dSYishai Hadas obj_id = MLX5_GET(modify_tis_in, in, tisn); 166e662e14dSYishai Hadas break; 167e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE: 168e662e14dSYishai Hadas obj_id = MLX5_GET(query_flow_table_in, in, table_id); 169e662e14dSYishai Hadas break; 170e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 171e662e14dSYishai Hadas obj_id = MLX5_GET(modify_flow_table_in, in, table_id); 172e662e14dSYishai Hadas break; 173e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_GROUP: 174e662e14dSYishai Hadas obj_id = MLX5_GET(query_flow_group_in, in, group_id); 175e662e14dSYishai Hadas break; 176e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 177e662e14dSYishai Hadas obj_id = MLX5_GET(query_fte_in, in, flow_index); 178e662e14dSYishai Hadas break; 179e662e14dSYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 180e662e14dSYishai Hadas obj_id = MLX5_GET(set_fte_in, in, flow_index); 181e662e14dSYishai Hadas break; 182e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_Q_COUNTER: 183e662e14dSYishai Hadas obj_id = MLX5_GET(query_q_counter_in, in, counter_set_id); 184e662e14dSYishai Hadas break; 185e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 186e662e14dSYishai Hadas obj_id = MLX5_GET(query_flow_counter_in, in, flow_counter_id); 187e662e14dSYishai Hadas break; 188e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 189e662e14dSYishai Hadas obj_id = MLX5_GET(general_obj_in_cmd_hdr, in, obj_id); 190e662e14dSYishai Hadas break; 191e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 192e662e14dSYishai Hadas obj_id = MLX5_GET(query_scheduling_element_in, in, 193e662e14dSYishai Hadas scheduling_element_id); 194e662e14dSYishai Hadas break; 195e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 196e662e14dSYishai Hadas obj_id = MLX5_GET(modify_scheduling_element_in, in, 197e662e14dSYishai Hadas scheduling_element_id); 198e662e14dSYishai Hadas break; 199e662e14dSYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 200e662e14dSYishai Hadas obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port); 201e662e14dSYishai Hadas break; 202e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 203e662e14dSYishai Hadas obj_id = MLX5_GET(query_l2_table_entry_in, in, table_index); 204e662e14dSYishai Hadas break; 205e662e14dSYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 206e662e14dSYishai Hadas obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index); 207e662e14dSYishai Hadas break; 208e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_QP: 209e662e14dSYishai Hadas obj_id = MLX5_GET(query_qp_in, in, qpn); 210e662e14dSYishai Hadas break; 211e662e14dSYishai Hadas case MLX5_CMD_OP_RST2INIT_QP: 212e662e14dSYishai Hadas obj_id = MLX5_GET(rst2init_qp_in, in, qpn); 213e662e14dSYishai Hadas break; 214e662e14dSYishai Hadas case MLX5_CMD_OP_INIT2RTR_QP: 215e662e14dSYishai Hadas obj_id = MLX5_GET(init2rtr_qp_in, in, qpn); 216e662e14dSYishai Hadas break; 217e662e14dSYishai Hadas case MLX5_CMD_OP_RTR2RTS_QP: 218e662e14dSYishai Hadas obj_id = MLX5_GET(rtr2rts_qp_in, in, qpn); 219e662e14dSYishai Hadas break; 220e662e14dSYishai Hadas case MLX5_CMD_OP_RTS2RTS_QP: 221e662e14dSYishai Hadas obj_id = MLX5_GET(rts2rts_qp_in, in, qpn); 222e662e14dSYishai Hadas break; 223e662e14dSYishai Hadas case MLX5_CMD_OP_SQERR2RTS_QP: 224e662e14dSYishai Hadas obj_id = MLX5_GET(sqerr2rts_qp_in, in, qpn); 225e662e14dSYishai Hadas break; 226e662e14dSYishai Hadas case MLX5_CMD_OP_2ERR_QP: 227e662e14dSYishai Hadas obj_id = MLX5_GET(qp_2err_in, in, qpn); 228e662e14dSYishai Hadas break; 229e662e14dSYishai Hadas case MLX5_CMD_OP_2RST_QP: 230e662e14dSYishai Hadas obj_id = MLX5_GET(qp_2rst_in, in, qpn); 231e662e14dSYishai Hadas break; 232e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_DCT: 233e662e14dSYishai Hadas obj_id = MLX5_GET(query_dct_in, in, dctn); 234e662e14dSYishai Hadas break; 235e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRQ: 236e662e14dSYishai Hadas obj_id = MLX5_GET(query_xrq_in, in, xrqn); 237e662e14dSYishai Hadas break; 238e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRC_SRQ: 239e662e14dSYishai Hadas obj_id = MLX5_GET(query_xrc_srq_in, in, xrc_srqn); 240e662e14dSYishai Hadas break; 241e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRC_SRQ: 242e662e14dSYishai Hadas obj_id = MLX5_GET(arm_xrc_srq_in, in, xrc_srqn); 243e662e14dSYishai Hadas break; 244e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SRQ: 245e662e14dSYishai Hadas obj_id = MLX5_GET(query_srq_in, in, srqn); 246e662e14dSYishai Hadas break; 247e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_RQ: 248e662e14dSYishai Hadas obj_id = MLX5_GET(arm_rq_in, in, srq_number); 249e662e14dSYishai Hadas break; 250e662e14dSYishai Hadas case MLX5_CMD_OP_DRAIN_DCT: 251e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 252e662e14dSYishai Hadas obj_id = MLX5_GET(drain_dct_in, in, dctn); 253e662e14dSYishai Hadas break; 254e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRQ: 255e662e14dSYishai Hadas obj_id = MLX5_GET(arm_xrq_in, in, xrqn); 256e662e14dSYishai Hadas break; 257e662e14dSYishai Hadas default: 258e662e14dSYishai Hadas return false; 259e662e14dSYishai Hadas } 260e662e14dSYishai Hadas 261e662e14dSYishai Hadas if (obj_id == obj->obj_id) 262e662e14dSYishai Hadas return true; 263e662e14dSYishai Hadas 264e662e14dSYishai Hadas return false; 265e662e14dSYishai Hadas } 266e662e14dSYishai Hadas 2677efce369SYishai Hadas static bool devx_is_obj_create_cmd(const void *in) 2687efce369SYishai Hadas { 2697efce369SYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 2707efce369SYishai Hadas 2717efce369SYishai Hadas switch (opcode) { 2727efce369SYishai Hadas case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 2737efce369SYishai Hadas case MLX5_CMD_OP_CREATE_MKEY: 2747efce369SYishai Hadas case MLX5_CMD_OP_CREATE_CQ: 2757efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_PD: 2767efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 2777efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RMP: 2787efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SQ: 2797efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQ: 2807efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQT: 2817efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIR: 2827efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIS: 2837efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_Q_COUNTER: 2847efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_TABLE: 2857efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_GROUP: 2867efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 287*60786f09SMark Bloch case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT: 2887efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 2897efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 2907efce369SYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 2917efce369SYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 2927efce369SYishai Hadas case MLX5_CMD_OP_CREATE_QP: 2937efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SRQ: 2947efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRC_SRQ: 2957efce369SYishai Hadas case MLX5_CMD_OP_CREATE_DCT: 2967efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRQ: 2977efce369SYishai Hadas case MLX5_CMD_OP_ATTACH_TO_MCG: 2987efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_XRCD: 2997efce369SYishai Hadas return true; 3007efce369SYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 3017efce369SYishai Hadas { 3027efce369SYishai Hadas u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 3037efce369SYishai Hadas if (op_mod == 0) 3047efce369SYishai Hadas return true; 3057efce369SYishai Hadas return false; 3067efce369SYishai Hadas } 3077efce369SYishai Hadas default: 3087efce369SYishai Hadas return false; 3097efce369SYishai Hadas } 3107efce369SYishai Hadas } 3117efce369SYishai Hadas 312e662e14dSYishai Hadas static bool devx_is_obj_modify_cmd(const void *in) 313e662e14dSYishai Hadas { 314e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 315e662e14dSYishai Hadas 316e662e14dSYishai Hadas switch (opcode) { 317e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 318e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_CQ: 319e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RMP: 320e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SQ: 321e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQ: 322e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQT: 323e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIR: 324e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIS: 325e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 326e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 327e662e14dSYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 328e662e14dSYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 329e662e14dSYishai Hadas case MLX5_CMD_OP_RST2INIT_QP: 330e662e14dSYishai Hadas case MLX5_CMD_OP_INIT2RTR_QP: 331e662e14dSYishai Hadas case MLX5_CMD_OP_RTR2RTS_QP: 332e662e14dSYishai Hadas case MLX5_CMD_OP_RTS2RTS_QP: 333e662e14dSYishai Hadas case MLX5_CMD_OP_SQERR2RTS_QP: 334e662e14dSYishai Hadas case MLX5_CMD_OP_2ERR_QP: 335e662e14dSYishai Hadas case MLX5_CMD_OP_2RST_QP: 336e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRC_SRQ: 337e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_RQ: 338e662e14dSYishai Hadas case MLX5_CMD_OP_DRAIN_DCT: 339e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 340e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRQ: 341e662e14dSYishai Hadas return true; 342e662e14dSYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 343e662e14dSYishai Hadas { 344e662e14dSYishai Hadas u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 345e662e14dSYishai Hadas 346e662e14dSYishai Hadas if (op_mod == 1) 347e662e14dSYishai Hadas return true; 348e662e14dSYishai Hadas return false; 349e662e14dSYishai Hadas } 350e662e14dSYishai Hadas default: 351e662e14dSYishai Hadas return false; 352e662e14dSYishai Hadas } 353e662e14dSYishai Hadas } 354e662e14dSYishai Hadas 355e662e14dSYishai Hadas static bool devx_is_obj_query_cmd(const void *in) 356e662e14dSYishai Hadas { 357e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 358e662e14dSYishai Hadas 359e662e14dSYishai Hadas switch (opcode) { 360e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 361e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MKEY: 362e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_CQ: 363e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RMP: 364e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SQ: 365e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQ: 366e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQT: 367e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIR: 368e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIS: 369e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_Q_COUNTER: 370e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE: 371e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_GROUP: 372e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 373e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 374e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 375e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 376e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 377e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_QP: 378e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SRQ: 379e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRC_SRQ: 380e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_DCT: 381e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRQ: 382e662e14dSYishai Hadas return true; 383e662e14dSYishai Hadas default: 384e662e14dSYishai Hadas return false; 385e662e14dSYishai Hadas } 386e662e14dSYishai Hadas } 387e662e14dSYishai Hadas 388e662e14dSYishai Hadas static bool devx_is_general_cmd(void *in) 3898aa8c95cSYishai Hadas { 3908aa8c95cSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 3918aa8c95cSYishai Hadas 3928aa8c95cSYishai Hadas switch (opcode) { 3938aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_HCA_CAP: 3948aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VPORT_STATE: 3958aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ADAPTER: 3968aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ISSI: 3978aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT: 3988aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ROCE_ADDRESS: 3998aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VNIC_ENV: 4008aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VPORT_COUNTER: 4018aa8c95cSYishai Hadas case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG: 4028aa8c95cSYishai Hadas case MLX5_CMD_OP_NOP: 4038aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_STATUS: 4048aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_PARAMS: 4058aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_STATISTICS: 4068aa8c95cSYishai Hadas return true; 4078aa8c95cSYishai Hadas default: 4088aa8c95cSYishai Hadas return false; 4098aa8c95cSYishai Hadas } 4108aa8c95cSYishai Hadas } 4118aa8c95cSYishai Hadas 412e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_EQN)( 413e83f0ecdSJason Gunthorpe struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 414f6fe01b7SYishai Hadas { 415e83f0ecdSJason Gunthorpe struct mlx5_ib_ucontext *c; 416e83f0ecdSJason Gunthorpe struct mlx5_ib_dev *dev; 417f6fe01b7SYishai Hadas int user_vector; 418f6fe01b7SYishai Hadas int dev_eqn; 419f6fe01b7SYishai Hadas unsigned int irqn; 420f6fe01b7SYishai Hadas int err; 421f6fe01b7SYishai Hadas 422f6fe01b7SYishai Hadas if (uverbs_copy_from(&user_vector, attrs, 423f6fe01b7SYishai Hadas MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC)) 424f6fe01b7SYishai Hadas return -EFAULT; 425f6fe01b7SYishai Hadas 426e83f0ecdSJason Gunthorpe c = devx_ufile2uctx(file); 427e83f0ecdSJason Gunthorpe if (IS_ERR(c)) 428e83f0ecdSJason Gunthorpe return PTR_ERR(c); 429e83f0ecdSJason Gunthorpe dev = to_mdev(c->ibucontext.device); 430e83f0ecdSJason Gunthorpe 431f6fe01b7SYishai Hadas err = mlx5_vector2eqn(dev->mdev, user_vector, &dev_eqn, &irqn); 432f6fe01b7SYishai Hadas if (err < 0) 433f6fe01b7SYishai Hadas return err; 434f6fe01b7SYishai Hadas 435f6fe01b7SYishai Hadas if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN, 436f6fe01b7SYishai Hadas &dev_eqn, sizeof(dev_eqn))) 437f6fe01b7SYishai Hadas return -EFAULT; 438f6fe01b7SYishai Hadas 439f6fe01b7SYishai Hadas return 0; 440f6fe01b7SYishai Hadas } 441f6fe01b7SYishai Hadas 4427c043e90SYishai Hadas /* 4437c043e90SYishai Hadas *Security note: 4447c043e90SYishai Hadas * The hardware protection mechanism works like this: Each device object that 4457c043e90SYishai Hadas * is subject to UAR doorbells (QP/SQ/CQ) gets a UAR ID (called uar_page in 4467c043e90SYishai Hadas * the device specification manual) upon its creation. Then upon doorbell, 4477c043e90SYishai Hadas * hardware fetches the object context for which the doorbell was rang, and 4487c043e90SYishai Hadas * validates that the UAR through which the DB was rang matches the UAR ID 4497c043e90SYishai Hadas * of the object. 4507c043e90SYishai Hadas * If no match the doorbell is silently ignored by the hardware. Of course, 4517c043e90SYishai Hadas * the user cannot ring a doorbell on a UAR that was not mapped to it. 4527c043e90SYishai Hadas * Now in devx, as the devx kernel does not manipulate the QP/SQ/CQ command 4537c043e90SYishai Hadas * mailboxes (except tagging them with UID), we expose to the user its UAR 4547c043e90SYishai Hadas * ID, so it can embed it in these objects in the expected specification 4557c043e90SYishai Hadas * format. So the only thing the user can do is hurt itself by creating a 4567c043e90SYishai Hadas * QP/SQ/CQ with a UAR ID other than his, and then in this case other users 4577c043e90SYishai Hadas * may ring a doorbell on its objects. 4587c043e90SYishai Hadas * The consequence of that will be that another user can schedule a QP/SQ 4597c043e90SYishai Hadas * of the buggy user for execution (just insert it to the hardware schedule 4607c043e90SYishai Hadas * queue or arm its CQ for event generation), no further harm is expected. 4617c043e90SYishai Hadas */ 462e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_UAR)( 463e83f0ecdSJason Gunthorpe struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 4647c043e90SYishai Hadas { 46522fa27fbSJason Gunthorpe struct mlx5_ib_ucontext *c; 46622fa27fbSJason Gunthorpe struct mlx5_ib_dev *dev; 4677c043e90SYishai Hadas u32 user_idx; 4687c043e90SYishai Hadas s32 dev_idx; 4697c043e90SYishai Hadas 47022fa27fbSJason Gunthorpe c = devx_ufile2uctx(file); 47122fa27fbSJason Gunthorpe if (IS_ERR(c)) 47222fa27fbSJason Gunthorpe return PTR_ERR(c); 47322fa27fbSJason Gunthorpe dev = to_mdev(c->ibucontext.device); 47422fa27fbSJason Gunthorpe 4757c043e90SYishai Hadas if (uverbs_copy_from(&user_idx, attrs, 4767c043e90SYishai Hadas MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX)) 4777c043e90SYishai Hadas return -EFAULT; 4787c043e90SYishai Hadas 47922fa27fbSJason Gunthorpe dev_idx = bfregn_to_uar_index(dev, &c->bfregi, user_idx, true); 4807c043e90SYishai Hadas if (dev_idx < 0) 4817c043e90SYishai Hadas return dev_idx; 4827c043e90SYishai Hadas 4837c043e90SYishai Hadas if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, 4847c043e90SYishai Hadas &dev_idx, sizeof(dev_idx))) 4857c043e90SYishai Hadas return -EFAULT; 4867c043e90SYishai Hadas 4877c043e90SYishai Hadas return 0; 4887c043e90SYishai Hadas } 4897c043e90SYishai Hadas 490e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)( 491e83f0ecdSJason Gunthorpe struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 4928aa8c95cSYishai Hadas { 49322fa27fbSJason Gunthorpe struct mlx5_ib_ucontext *c; 49422fa27fbSJason Gunthorpe struct mlx5_ib_dev *dev; 4957efce369SYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr( 4967efce369SYishai Hadas attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN); 4978aa8c95cSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 4988aa8c95cSYishai Hadas MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT); 4998aa8c95cSYishai Hadas void *cmd_out; 5008aa8c95cSYishai Hadas int err; 5018aa8c95cSYishai Hadas 50222fa27fbSJason Gunthorpe c = devx_ufile2uctx(file); 50322fa27fbSJason Gunthorpe if (IS_ERR(c)) 50422fa27fbSJason Gunthorpe return PTR_ERR(c); 50522fa27fbSJason Gunthorpe dev = to_mdev(c->ibucontext.device); 50622fa27fbSJason Gunthorpe 5078aa8c95cSYishai Hadas if (!c->devx_uid) 5088aa8c95cSYishai Hadas return -EPERM; 5098aa8c95cSYishai Hadas 5108aa8c95cSYishai Hadas /* Only white list of some general HCA commands are allowed for this method. */ 5118aa8c95cSYishai Hadas if (!devx_is_general_cmd(cmd_in)) 5128aa8c95cSYishai Hadas return -EINVAL; 5138aa8c95cSYishai Hadas 514b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 515b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 516b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 5178aa8c95cSYishai Hadas 5188aa8c95cSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 5198aa8c95cSYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 5208aa8c95cSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN), 5218aa8c95cSYishai Hadas cmd_out, cmd_out_len); 5228aa8c95cSYishai Hadas if (err) 5238aa8c95cSYishai Hadas return err; 524b61815e2SJason Gunthorpe 525b61815e2SJason Gunthorpe return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out, 526b61815e2SJason Gunthorpe cmd_out_len); 5278aa8c95cSYishai Hadas } 5288aa8c95cSYishai Hadas 5297efce369SYishai Hadas static void devx_obj_build_destroy_cmd(void *in, void *out, void *din, 5307efce369SYishai Hadas u32 *dinlen, 5317efce369SYishai Hadas u32 *obj_id) 5327efce369SYishai Hadas { 5337efce369SYishai Hadas u16 obj_type = MLX5_GET(general_obj_in_cmd_hdr, in, obj_type); 5347efce369SYishai Hadas u16 uid = MLX5_GET(general_obj_in_cmd_hdr, in, uid); 5357efce369SYishai Hadas 5367efce369SYishai Hadas *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 5377efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr); 5387efce369SYishai Hadas 5397efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, obj_id, *obj_id); 5407efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, uid, uid); 5417efce369SYishai Hadas 5427efce369SYishai Hadas switch (MLX5_GET(general_obj_in_cmd_hdr, in, opcode)) { 5437efce369SYishai Hadas case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 5447efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 5457efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, obj_type, obj_type); 5467efce369SYishai Hadas break; 5477efce369SYishai Hadas 5487efce369SYishai Hadas case MLX5_CMD_OP_CREATE_MKEY: 5497efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_MKEY); 5507efce369SYishai Hadas break; 5517efce369SYishai Hadas case MLX5_CMD_OP_CREATE_CQ: 5527efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_CQ); 5537efce369SYishai Hadas break; 5547efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_PD: 5557efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_PD); 5567efce369SYishai Hadas break; 5577efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 5587efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5597efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN); 5607efce369SYishai Hadas break; 5617efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RMP: 5627efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RMP); 5637efce369SYishai Hadas break; 5647efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SQ: 5657efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SQ); 5667efce369SYishai Hadas break; 5677efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQ: 5687efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQ); 5697efce369SYishai Hadas break; 5707efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQT: 5717efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT); 5727efce369SYishai Hadas break; 5737efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIR: 5747efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIR); 5757efce369SYishai Hadas break; 5767efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIS: 5777efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS); 5787efce369SYishai Hadas break; 5797efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_Q_COUNTER: 5807efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5817efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_Q_COUNTER); 5827efce369SYishai Hadas break; 5837efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_TABLE: 5847efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_table_in); 5857efce369SYishai Hadas *obj_id = MLX5_GET(create_flow_table_out, out, table_id); 5867efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, other_vport, 5877efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, other_vport)); 5887efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, vport_number, 5897efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, vport_number)); 5907efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, table_type, 5917efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, table_type)); 5927efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, table_id, *obj_id); 5937efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5947efce369SYishai Hadas MLX5_CMD_OP_DESTROY_FLOW_TABLE); 5957efce369SYishai Hadas break; 5967efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_GROUP: 5977efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_group_in); 5987efce369SYishai Hadas *obj_id = MLX5_GET(create_flow_group_out, out, group_id); 5997efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, other_vport, 6007efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, other_vport)); 6017efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, vport_number, 6027efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, vport_number)); 6037efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, table_type, 6047efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, table_type)); 6057efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, table_id, 6067efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, table_id)); 6077efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, group_id, *obj_id); 6087efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6097efce369SYishai Hadas MLX5_CMD_OP_DESTROY_FLOW_GROUP); 6107efce369SYishai Hadas break; 6117efce369SYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 6127efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_fte_in); 6137efce369SYishai Hadas *obj_id = MLX5_GET(set_fte_in, in, flow_index); 6147efce369SYishai Hadas MLX5_SET(delete_fte_in, din, other_vport, 6157efce369SYishai Hadas MLX5_GET(set_fte_in, in, other_vport)); 6167efce369SYishai Hadas MLX5_SET(delete_fte_in, din, vport_number, 6177efce369SYishai Hadas MLX5_GET(set_fte_in, in, vport_number)); 6187efce369SYishai Hadas MLX5_SET(delete_fte_in, din, table_type, 6197efce369SYishai Hadas MLX5_GET(set_fte_in, in, table_type)); 6207efce369SYishai Hadas MLX5_SET(delete_fte_in, din, table_id, 6217efce369SYishai Hadas MLX5_GET(set_fte_in, in, table_id)); 6227efce369SYishai Hadas MLX5_SET(delete_fte_in, din, flow_index, *obj_id); 6237efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6247efce369SYishai Hadas MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); 6257efce369SYishai Hadas break; 6267efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 6277efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6287efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_FLOW_COUNTER); 6297efce369SYishai Hadas break; 630*60786f09SMark Bloch case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT: 6317efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 632*60786f09SMark Bloch MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT); 6337efce369SYishai Hadas break; 6347efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 6357efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6367efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT); 6377efce369SYishai Hadas break; 6387efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 6397efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_scheduling_element_in); 6407efce369SYishai Hadas *obj_id = MLX5_GET(create_scheduling_element_out, out, 6417efce369SYishai Hadas scheduling_element_id); 6427efce369SYishai Hadas MLX5_SET(destroy_scheduling_element_in, din, 6437efce369SYishai Hadas scheduling_hierarchy, 6447efce369SYishai Hadas MLX5_GET(create_scheduling_element_in, in, 6457efce369SYishai Hadas scheduling_hierarchy)); 6467efce369SYishai Hadas MLX5_SET(destroy_scheduling_element_in, din, 6477efce369SYishai Hadas scheduling_element_id, *obj_id); 6487efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6497efce369SYishai Hadas MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT); 6507efce369SYishai Hadas break; 6517efce369SYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 6527efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_vxlan_udp_dport_in); 6537efce369SYishai Hadas *obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port); 6547efce369SYishai Hadas MLX5_SET(delete_vxlan_udp_dport_in, din, vxlan_udp_port, *obj_id); 6557efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6567efce369SYishai Hadas MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT); 6577efce369SYishai Hadas break; 6587efce369SYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 6597efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_l2_table_entry_in); 6607efce369SYishai Hadas *obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index); 6617efce369SYishai Hadas MLX5_SET(delete_l2_table_entry_in, din, table_index, *obj_id); 6627efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6637efce369SYishai Hadas MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY); 6647efce369SYishai Hadas break; 6657efce369SYishai Hadas case MLX5_CMD_OP_CREATE_QP: 6667efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_QP); 6677efce369SYishai Hadas break; 6687efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SRQ: 6697efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SRQ); 6707efce369SYishai Hadas break; 6717efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRC_SRQ: 6727efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 6737efce369SYishai Hadas MLX5_CMD_OP_DESTROY_XRC_SRQ); 6747efce369SYishai Hadas break; 6757efce369SYishai Hadas case MLX5_CMD_OP_CREATE_DCT: 6767efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_DCT); 6777efce369SYishai Hadas break; 6787efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRQ: 6797efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_XRQ); 6807efce369SYishai Hadas break; 6817efce369SYishai Hadas case MLX5_CMD_OP_ATTACH_TO_MCG: 6827efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(detach_from_mcg_in); 6837efce369SYishai Hadas MLX5_SET(detach_from_mcg_in, din, qpn, 6847efce369SYishai Hadas MLX5_GET(attach_to_mcg_in, in, qpn)); 6857efce369SYishai Hadas memcpy(MLX5_ADDR_OF(detach_from_mcg_in, din, multicast_gid), 6867efce369SYishai Hadas MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid), 6877efce369SYishai Hadas MLX5_FLD_SZ_BYTES(attach_to_mcg_in, multicast_gid)); 6887efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DETACH_FROM_MCG); 6897efce369SYishai Hadas break; 6907efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_XRCD: 6917efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD); 6927efce369SYishai Hadas break; 6937efce369SYishai Hadas default: 6947efce369SYishai Hadas /* The entry must match to one of the devx_is_obj_create_cmd */ 6957efce369SYishai Hadas WARN_ON(true); 6967efce369SYishai Hadas break; 6977efce369SYishai Hadas } 6987efce369SYishai Hadas } 6997efce369SYishai Hadas 7007efce369SYishai Hadas static int devx_obj_cleanup(struct ib_uobject *uobject, 7017efce369SYishai Hadas enum rdma_remove_reason why) 7027efce369SYishai Hadas { 7037efce369SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 7047efce369SYishai Hadas struct devx_obj *obj = uobject->object; 7057efce369SYishai Hadas int ret; 7067efce369SYishai Hadas 7077efce369SYishai Hadas ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out)); 7081c77483eSYishai Hadas if (ib_is_destroy_retryable(ret, why, uobject)) 7097efce369SYishai Hadas return ret; 7107efce369SYishai Hadas 7117efce369SYishai Hadas kfree(obj); 7127efce369SYishai Hadas return ret; 7137efce369SYishai Hadas } 7147efce369SYishai Hadas 715e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)( 716e83f0ecdSJason Gunthorpe struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 7177efce369SYishai Hadas { 7187efce369SYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN); 7197efce369SYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 7207efce369SYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT); 7217efce369SYishai Hadas void *cmd_out; 722c36ee46dSJason Gunthorpe struct ib_uobject *uobj = uverbs_attr_get_uobject( 723c36ee46dSJason Gunthorpe attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE); 724c36ee46dSJason Gunthorpe struct mlx5_ib_ucontext *c = to_mucontext(uobj->context); 725c36ee46dSJason Gunthorpe struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 7267efce369SYishai Hadas struct devx_obj *obj; 7277efce369SYishai Hadas int err; 7287efce369SYishai Hadas 7297efce369SYishai Hadas if (!c->devx_uid) 7307efce369SYishai Hadas return -EPERM; 7317efce369SYishai Hadas 7327efce369SYishai Hadas if (!devx_is_obj_create_cmd(cmd_in)) 7337efce369SYishai Hadas return -EINVAL; 7347efce369SYishai Hadas 735b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 736b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 737b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 738b61815e2SJason Gunthorpe 7397efce369SYishai Hadas obj = kzalloc(sizeof(struct devx_obj), GFP_KERNEL); 7407efce369SYishai Hadas if (!obj) 7417efce369SYishai Hadas return -ENOMEM; 7427efce369SYishai Hadas 7437efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 7447efce369SYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 7457efce369SYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN), 7467efce369SYishai Hadas cmd_out, cmd_out_len); 7477efce369SYishai Hadas if (err) 748b61815e2SJason Gunthorpe goto obj_free; 7497efce369SYishai Hadas 7507efce369SYishai Hadas uobj->object = obj; 7517efce369SYishai Hadas obj->mdev = dev->mdev; 7527efce369SYishai Hadas devx_obj_build_destroy_cmd(cmd_in, cmd_out, obj->dinbox, &obj->dinlen, &obj->obj_id); 7537efce369SYishai Hadas WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32)); 7547efce369SYishai Hadas 7557efce369SYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len); 7567efce369SYishai Hadas if (err) 757b61815e2SJason Gunthorpe goto obj_free; 7587efce369SYishai Hadas 7597efce369SYishai Hadas return 0; 7607efce369SYishai Hadas 7617efce369SYishai Hadas obj_free: 7627efce369SYishai Hadas kfree(obj); 7637efce369SYishai Hadas return err; 7647efce369SYishai Hadas } 7657efce369SYishai Hadas 766e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MODIFY)( 767e83f0ecdSJason Gunthorpe struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 768e662e14dSYishai Hadas { 769e662e14dSYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN); 770e662e14dSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 771e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT); 772e662e14dSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 773e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE); 774c36ee46dSJason Gunthorpe struct mlx5_ib_ucontext *c = to_mucontext(uobj->context); 775c36ee46dSJason Gunthorpe struct devx_obj *obj = uobj->object; 776e662e14dSYishai Hadas void *cmd_out; 777e662e14dSYishai Hadas int err; 778e662e14dSYishai Hadas 779e662e14dSYishai Hadas if (!c->devx_uid) 780e662e14dSYishai Hadas return -EPERM; 781e662e14dSYishai Hadas 782e662e14dSYishai Hadas if (!devx_is_obj_modify_cmd(cmd_in)) 783e662e14dSYishai Hadas return -EINVAL; 784e662e14dSYishai Hadas 785c36ee46dSJason Gunthorpe if (!devx_is_valid_obj_id(obj, cmd_in)) 786e662e14dSYishai Hadas return -EINVAL; 787e662e14dSYishai Hadas 788b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 789b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 790b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 791e662e14dSYishai Hadas 792e662e14dSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 793c36ee46dSJason Gunthorpe err = mlx5_cmd_exec(obj->mdev, cmd_in, 794e662e14dSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN), 795e662e14dSYishai Hadas cmd_out, cmd_out_len); 796e662e14dSYishai Hadas if (err) 797e662e14dSYishai Hadas return err; 798b61815e2SJason Gunthorpe 799b61815e2SJason Gunthorpe return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 800b61815e2SJason Gunthorpe cmd_out, cmd_out_len); 801e662e14dSYishai Hadas } 802e662e14dSYishai Hadas 803e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)( 804e83f0ecdSJason Gunthorpe struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 805e662e14dSYishai Hadas { 806e662e14dSYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN); 807e662e14dSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 808e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT); 809e662e14dSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 810e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE); 811c36ee46dSJason Gunthorpe struct mlx5_ib_ucontext *c = to_mucontext(uobj->context); 812c36ee46dSJason Gunthorpe struct devx_obj *obj = uobj->object; 813e662e14dSYishai Hadas void *cmd_out; 814e662e14dSYishai Hadas int err; 815e662e14dSYishai Hadas 816e662e14dSYishai Hadas if (!c->devx_uid) 817e662e14dSYishai Hadas return -EPERM; 818e662e14dSYishai Hadas 819e662e14dSYishai Hadas if (!devx_is_obj_query_cmd(cmd_in)) 820e662e14dSYishai Hadas return -EINVAL; 821e662e14dSYishai Hadas 822c36ee46dSJason Gunthorpe if (!devx_is_valid_obj_id(obj, cmd_in)) 823e662e14dSYishai Hadas return -EINVAL; 824e662e14dSYishai Hadas 825b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 826b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 827b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 828e662e14dSYishai Hadas 829e662e14dSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 830c36ee46dSJason Gunthorpe err = mlx5_cmd_exec(obj->mdev, cmd_in, 831e662e14dSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN), 832e662e14dSYishai Hadas cmd_out, cmd_out_len); 833e662e14dSYishai Hadas if (err) 834e662e14dSYishai Hadas return err; 835b61815e2SJason Gunthorpe 836b61815e2SJason Gunthorpe return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, 837b61815e2SJason Gunthorpe cmd_out, cmd_out_len); 838e662e14dSYishai Hadas } 839e662e14dSYishai Hadas 840aeae9457SYishai Hadas static int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext, 841aeae9457SYishai Hadas struct uverbs_attr_bundle *attrs, 842aeae9457SYishai Hadas struct devx_umem *obj) 843aeae9457SYishai Hadas { 844aeae9457SYishai Hadas u64 addr; 845aeae9457SYishai Hadas size_t size; 846bccd0622SJason Gunthorpe u32 access; 847aeae9457SYishai Hadas int npages; 848aeae9457SYishai Hadas int err; 849aeae9457SYishai Hadas u32 page_mask; 850aeae9457SYishai Hadas 851aeae9457SYishai Hadas if (uverbs_copy_from(&addr, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR) || 852bccd0622SJason Gunthorpe uverbs_copy_from(&size, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_LEN)) 853aeae9457SYishai Hadas return -EFAULT; 854aeae9457SYishai Hadas 855bccd0622SJason Gunthorpe err = uverbs_get_flags32(&access, attrs, 856bccd0622SJason Gunthorpe MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, 857bccd0622SJason Gunthorpe IB_ACCESS_SUPPORTED); 858bccd0622SJason Gunthorpe if (err) 859bccd0622SJason Gunthorpe return err; 860bccd0622SJason Gunthorpe 861aeae9457SYishai Hadas err = ib_check_mr_access(access); 862aeae9457SYishai Hadas if (err) 863aeae9457SYishai Hadas return err; 864aeae9457SYishai Hadas 865aeae9457SYishai Hadas obj->umem = ib_umem_get(ucontext, addr, size, access, 0); 866aeae9457SYishai Hadas if (IS_ERR(obj->umem)) 867aeae9457SYishai Hadas return PTR_ERR(obj->umem); 868aeae9457SYishai Hadas 869aeae9457SYishai Hadas mlx5_ib_cont_pages(obj->umem, obj->umem->address, 870aeae9457SYishai Hadas MLX5_MKEY_PAGE_SHIFT_MASK, &npages, 871aeae9457SYishai Hadas &obj->page_shift, &obj->ncont, NULL); 872aeae9457SYishai Hadas 873aeae9457SYishai Hadas if (!npages) { 874aeae9457SYishai Hadas ib_umem_release(obj->umem); 875aeae9457SYishai Hadas return -EINVAL; 876aeae9457SYishai Hadas } 877aeae9457SYishai Hadas 878aeae9457SYishai Hadas page_mask = (1 << obj->page_shift) - 1; 879aeae9457SYishai Hadas obj->page_offset = obj->umem->address & page_mask; 880aeae9457SYishai Hadas 881aeae9457SYishai Hadas return 0; 882aeae9457SYishai Hadas } 883aeae9457SYishai Hadas 884b61815e2SJason Gunthorpe static int devx_umem_reg_cmd_alloc(struct uverbs_attr_bundle *attrs, 885b61815e2SJason Gunthorpe struct devx_umem *obj, 886aeae9457SYishai Hadas struct devx_umem_reg_cmd *cmd) 887aeae9457SYishai Hadas { 888aeae9457SYishai Hadas cmd->inlen = MLX5_ST_SZ_BYTES(create_umem_in) + 889aeae9457SYishai Hadas (MLX5_ST_SZ_BYTES(mtt) * obj->ncont); 890b61815e2SJason Gunthorpe cmd->in = uverbs_zalloc(attrs, cmd->inlen); 891b61815e2SJason Gunthorpe return PTR_ERR_OR_ZERO(cmd->in); 892aeae9457SYishai Hadas } 893aeae9457SYishai Hadas 894aeae9457SYishai Hadas static void devx_umem_reg_cmd_build(struct mlx5_ib_dev *dev, 895aeae9457SYishai Hadas struct devx_umem *obj, 896aeae9457SYishai Hadas struct devx_umem_reg_cmd *cmd) 897aeae9457SYishai Hadas { 898aeae9457SYishai Hadas void *umem; 899aeae9457SYishai Hadas __be64 *mtt; 900aeae9457SYishai Hadas 901aeae9457SYishai Hadas umem = MLX5_ADDR_OF(create_umem_in, cmd->in, umem); 902aeae9457SYishai Hadas mtt = (__be64 *)MLX5_ADDR_OF(umem, umem, mtt); 903aeae9457SYishai Hadas 904aeae9457SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd->in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 905aeae9457SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd->in, obj_type, MLX5_OBJ_TYPE_UMEM); 906aeae9457SYishai Hadas MLX5_SET64(umem, umem, num_of_mtt, obj->ncont); 907aeae9457SYishai Hadas MLX5_SET(umem, umem, log_page_size, obj->page_shift - 908aeae9457SYishai Hadas MLX5_ADAPTER_PAGE_SHIFT); 909aeae9457SYishai Hadas MLX5_SET(umem, umem, page_offset, obj->page_offset); 910aeae9457SYishai Hadas mlx5_ib_populate_pas(dev, obj->umem, obj->page_shift, mtt, 911aeae9457SYishai Hadas (obj->umem->writable ? MLX5_IB_MTT_WRITE : 0) | 912aeae9457SYishai Hadas MLX5_IB_MTT_READ); 913aeae9457SYishai Hadas } 914aeae9457SYishai Hadas 915e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_REG)( 916e83f0ecdSJason Gunthorpe struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) 917aeae9457SYishai Hadas { 918aeae9457SYishai Hadas struct devx_umem_reg_cmd cmd; 919aeae9457SYishai Hadas struct devx_umem *obj; 920c36ee46dSJason Gunthorpe struct ib_uobject *uobj = uverbs_attr_get_uobject( 921c36ee46dSJason Gunthorpe attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE); 922aeae9457SYishai Hadas u32 obj_id; 923c36ee46dSJason Gunthorpe struct mlx5_ib_ucontext *c = to_mucontext(uobj->context); 924c36ee46dSJason Gunthorpe struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 925aeae9457SYishai Hadas int err; 926aeae9457SYishai Hadas 927aeae9457SYishai Hadas if (!c->devx_uid) 928aeae9457SYishai Hadas return -EPERM; 929aeae9457SYishai Hadas 930aeae9457SYishai Hadas obj = kzalloc(sizeof(struct devx_umem), GFP_KERNEL); 931aeae9457SYishai Hadas if (!obj) 932aeae9457SYishai Hadas return -ENOMEM; 933aeae9457SYishai Hadas 934aeae9457SYishai Hadas err = devx_umem_get(dev, &c->ibucontext, attrs, obj); 935aeae9457SYishai Hadas if (err) 936aeae9457SYishai Hadas goto err_obj_free; 937aeae9457SYishai Hadas 938b61815e2SJason Gunthorpe err = devx_umem_reg_cmd_alloc(attrs, obj, &cmd); 939aeae9457SYishai Hadas if (err) 940aeae9457SYishai Hadas goto err_umem_release; 941aeae9457SYishai Hadas 942aeae9457SYishai Hadas devx_umem_reg_cmd_build(dev, obj, &cmd); 943aeae9457SYishai Hadas 944aeae9457SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd.in, uid, c->devx_uid); 945aeae9457SYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd.in, cmd.inlen, cmd.out, 946aeae9457SYishai Hadas sizeof(cmd.out)); 947aeae9457SYishai Hadas if (err) 948b61815e2SJason Gunthorpe goto err_umem_release; 949aeae9457SYishai Hadas 950aeae9457SYishai Hadas obj->mdev = dev->mdev; 951aeae9457SYishai Hadas uobj->object = obj; 952aeae9457SYishai Hadas devx_obj_build_destroy_cmd(cmd.in, cmd.out, obj->dinbox, &obj->dinlen, &obj_id); 953aeae9457SYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, &obj_id, sizeof(obj_id)); 954aeae9457SYishai Hadas if (err) 955aeae9457SYishai Hadas goto err_umem_destroy; 956aeae9457SYishai Hadas 957aeae9457SYishai Hadas return 0; 958aeae9457SYishai Hadas 959aeae9457SYishai Hadas err_umem_destroy: 960aeae9457SYishai Hadas mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, cmd.out, sizeof(cmd.out)); 961aeae9457SYishai Hadas err_umem_release: 962aeae9457SYishai Hadas ib_umem_release(obj->umem); 963aeae9457SYishai Hadas err_obj_free: 964aeae9457SYishai Hadas kfree(obj); 965aeae9457SYishai Hadas return err; 966aeae9457SYishai Hadas } 967aeae9457SYishai Hadas 968aeae9457SYishai Hadas static int devx_umem_cleanup(struct ib_uobject *uobject, 969aeae9457SYishai Hadas enum rdma_remove_reason why) 970aeae9457SYishai Hadas { 971aeae9457SYishai Hadas struct devx_umem *obj = uobject->object; 972aeae9457SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 973aeae9457SYishai Hadas int err; 974aeae9457SYishai Hadas 975aeae9457SYishai Hadas err = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out)); 9761c77483eSYishai Hadas if (ib_is_destroy_retryable(err, why, uobject)) 977aeae9457SYishai Hadas return err; 978aeae9457SYishai Hadas 979aeae9457SYishai Hadas ib_umem_release(obj->umem); 980aeae9457SYishai Hadas kfree(obj); 981aeae9457SYishai Hadas return 0; 982aeae9457SYishai Hadas } 983aeae9457SYishai Hadas 9849a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 9859a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_UMEM_REG, 9869a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE, 987aeae9457SYishai Hadas MLX5_IB_OBJECT_DEVX_UMEM, 988aeae9457SYishai Hadas UVERBS_ACCESS_NEW, 98983bb4442SJason Gunthorpe UA_MANDATORY), 9909a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR, 9919a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u64), 99283bb4442SJason Gunthorpe UA_MANDATORY), 9939a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_LEN, 9949a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u64), 99583bb4442SJason Gunthorpe UA_MANDATORY), 996bccd0622SJason Gunthorpe UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, 997bccd0622SJason Gunthorpe enum ib_access_flags), 9989a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, 9999a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 100083bb4442SJason Gunthorpe UA_MANDATORY)); 1001aeae9457SYishai Hadas 1002528922afSYishai Hadas DECLARE_UVERBS_NAMED_METHOD_DESTROY( 10039a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_UMEM_DEREG, 10049a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE, 1005aeae9457SYishai Hadas MLX5_IB_OBJECT_DEVX_UMEM, 1006aeae9457SYishai Hadas UVERBS_ACCESS_DESTROY, 100783bb4442SJason Gunthorpe UA_MANDATORY)); 1008aeae9457SYishai Hadas 10099a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 10109a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_QUERY_EQN, 10119a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC, 10129a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 101383bb4442SJason Gunthorpe UA_MANDATORY), 10149a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN, 10159a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 101683bb4442SJason Gunthorpe UA_MANDATORY)); 1017f6fe01b7SYishai Hadas 10189a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 10199a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_QUERY_UAR, 10209a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX, 10219a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 102283bb4442SJason Gunthorpe UA_MANDATORY), 10239a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, 10249a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 102583bb4442SJason Gunthorpe UA_MANDATORY)); 10267c043e90SYishai Hadas 10279a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 10289a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OTHER, 10299a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 10309a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OTHER_CMD_IN, 10318aa8c95cSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 103283bb4442SJason Gunthorpe UA_MANDATORY, 103383bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 10349a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 10359a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, 10367efce369SYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1037540cd692SJason Gunthorpe UA_MANDATORY)); 10387efce369SYishai Hadas 10399a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 10409a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_CREATE, 10419a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE, 10429a119cd5SJason Gunthorpe MLX5_IB_OBJECT_DEVX_OBJ, 10439a119cd5SJason Gunthorpe UVERBS_ACCESS_NEW, 104483bb4442SJason Gunthorpe UA_MANDATORY), 10459a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 10469a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN, 10479a119cd5SJason Gunthorpe UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 104883bb4442SJason Gunthorpe UA_MANDATORY, 104983bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 10509a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 10519a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, 10529a119cd5SJason Gunthorpe UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1053540cd692SJason Gunthorpe UA_MANDATORY)); 10549a119cd5SJason Gunthorpe 1055528922afSYishai Hadas DECLARE_UVERBS_NAMED_METHOD_DESTROY( 10569a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_DESTROY, 10579a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE, 10587efce369SYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 10597efce369SYishai Hadas UVERBS_ACCESS_DESTROY, 106083bb4442SJason Gunthorpe UA_MANDATORY)); 10617efce369SYishai Hadas 10629a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 10639a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_MODIFY, 10649a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE, 1065e662e14dSYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 1066e662e14dSYishai Hadas UVERBS_ACCESS_WRITE, 106783bb4442SJason Gunthorpe UA_MANDATORY), 10689a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 10699a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, 1070e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 107183bb4442SJason Gunthorpe UA_MANDATORY, 107283bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 10739a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 10749a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 1075e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1076540cd692SJason Gunthorpe UA_MANDATORY)); 1077e662e14dSYishai Hadas 10789a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 10799a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_QUERY, 10809a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE, 1081e662e14dSYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 1082e662e14dSYishai Hadas UVERBS_ACCESS_READ, 108383bb4442SJason Gunthorpe UA_MANDATORY), 10849a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 10859a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, 1086e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 108783bb4442SJason Gunthorpe UA_MANDATORY, 108883bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 10899a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 10909a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, 1091e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1092540cd692SJason Gunthorpe UA_MANDATORY)); 1093e662e14dSYishai Hadas 10946c61d2a5SJason Gunthorpe DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX, 10957c043e90SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER), 1096f6fe01b7SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR), 1097f6fe01b7SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_EQN)); 10988aa8c95cSYishai Hadas 10996c61d2a5SJason Gunthorpe DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ, 11009a119cd5SJason Gunthorpe UVERBS_TYPE_ALLOC_IDR(devx_obj_cleanup), 11017efce369SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE), 1102e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY), 1103e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY), 1104e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY)); 11057efce369SYishai Hadas 11066c61d2a5SJason Gunthorpe DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM, 11079a119cd5SJason Gunthorpe UVERBS_TYPE_ALLOC_IDR(devx_umem_cleanup), 1108aeae9457SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG), 1109aeae9457SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG)); 1110aeae9457SYishai Hadas 11116c61d2a5SJason Gunthorpe DECLARE_UVERBS_OBJECT_TREE(devx_objects, 11127efce369SYishai Hadas &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX), 1113aeae9457SYishai Hadas &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ), 1114aeae9457SYishai Hadas &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM)); 1115c59450c4SYishai Hadas 1116c59450c4SYishai Hadas const struct uverbs_object_tree_def *mlx5_ib_get_devx_tree(void) 1117c59450c4SYishai Hadas { 1118c59450c4SYishai Hadas return &devx_objects; 1119c59450c4SYishai Hadas } 1120