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 278aa8c95cSYishai Hadas static struct mlx5_ib_ucontext *devx_ufile2uctx(struct ib_uverbs_file *file) 288aa8c95cSYishai Hadas { 298aa8c95cSYishai Hadas return to_mucontext(ib_uverbs_get_ucontext(file)); 308aa8c95cSYishai Hadas } 318aa8c95cSYishai Hadas 32a8b92ca1SYishai Hadas int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, struct mlx5_ib_ucontext *context) 33a8b92ca1SYishai Hadas { 34a8b92ca1SYishai Hadas u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0}; 35a8b92ca1SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 36a8b92ca1SYishai Hadas u64 general_obj_types; 37a8b92ca1SYishai Hadas void *uctx; 38a8b92ca1SYishai Hadas void *hdr; 39a8b92ca1SYishai Hadas int err; 40a8b92ca1SYishai Hadas 41a8b92ca1SYishai Hadas uctx = MLX5_ADDR_OF(create_uctx_in, in, uctx); 42a8b92ca1SYishai Hadas hdr = MLX5_ADDR_OF(create_uctx_in, in, hdr); 43a8b92ca1SYishai Hadas 44a8b92ca1SYishai Hadas general_obj_types = MLX5_CAP_GEN_64(dev->mdev, general_obj_types); 45a8b92ca1SYishai Hadas if (!(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UCTX) || 46a8b92ca1SYishai Hadas !(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_UMEM)) 47a8b92ca1SYishai Hadas return -EINVAL; 48a8b92ca1SYishai Hadas 49a8b92ca1SYishai Hadas if (!capable(CAP_NET_RAW)) 50a8b92ca1SYishai Hadas return -EPERM; 51a8b92ca1SYishai Hadas 52a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 53a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, MLX5_OBJ_TYPE_UCTX); 54a8b92ca1SYishai Hadas 55a8b92ca1SYishai Hadas err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 56a8b92ca1SYishai Hadas if (err) 57a8b92ca1SYishai Hadas return err; 58a8b92ca1SYishai Hadas 59a8b92ca1SYishai Hadas context->devx_uid = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 60a8b92ca1SYishai Hadas return 0; 61a8b92ca1SYishai Hadas } 62a8b92ca1SYishai Hadas 63a8b92ca1SYishai Hadas void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, 64a8b92ca1SYishai Hadas struct mlx5_ib_ucontext *context) 65a8b92ca1SYishai Hadas { 66a8b92ca1SYishai Hadas u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0}; 67a8b92ca1SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 68a8b92ca1SYishai Hadas 69a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 70a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_UCTX); 71a8b92ca1SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, context->devx_uid); 72a8b92ca1SYishai Hadas 73a8b92ca1SYishai Hadas mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 74a8b92ca1SYishai Hadas } 758aa8c95cSYishai Hadas 76*e662e14dSYishai Hadas static int devx_is_valid_obj_id(struct devx_obj *obj, const void *in) 77*e662e14dSYishai Hadas { 78*e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 79*e662e14dSYishai Hadas u32 obj_id; 80*e662e14dSYishai Hadas 81*e662e14dSYishai Hadas switch (opcode) { 82*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 83*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 84*e662e14dSYishai Hadas obj_id = MLX5_GET(general_obj_in_cmd_hdr, in, obj_id); 85*e662e14dSYishai Hadas break; 86*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MKEY: 87*e662e14dSYishai Hadas obj_id = MLX5_GET(query_mkey_in, in, mkey_index); 88*e662e14dSYishai Hadas break; 89*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_CQ: 90*e662e14dSYishai Hadas obj_id = MLX5_GET(query_cq_in, in, cqn); 91*e662e14dSYishai Hadas break; 92*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_CQ: 93*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_cq_in, in, cqn); 94*e662e14dSYishai Hadas break; 95*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SQ: 96*e662e14dSYishai Hadas obj_id = MLX5_GET(query_sq_in, in, sqn); 97*e662e14dSYishai Hadas break; 98*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SQ: 99*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_sq_in, in, sqn); 100*e662e14dSYishai Hadas break; 101*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQ: 102*e662e14dSYishai Hadas obj_id = MLX5_GET(query_rq_in, in, rqn); 103*e662e14dSYishai Hadas break; 104*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQ: 105*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_rq_in, in, rqn); 106*e662e14dSYishai Hadas break; 107*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RMP: 108*e662e14dSYishai Hadas obj_id = MLX5_GET(query_rmp_in, in, rmpn); 109*e662e14dSYishai Hadas break; 110*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RMP: 111*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_rmp_in, in, rmpn); 112*e662e14dSYishai Hadas break; 113*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQT: 114*e662e14dSYishai Hadas obj_id = MLX5_GET(query_rqt_in, in, rqtn); 115*e662e14dSYishai Hadas break; 116*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQT: 117*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_rqt_in, in, rqtn); 118*e662e14dSYishai Hadas break; 119*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIR: 120*e662e14dSYishai Hadas obj_id = MLX5_GET(query_tir_in, in, tirn); 121*e662e14dSYishai Hadas break; 122*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIR: 123*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_tir_in, in, tirn); 124*e662e14dSYishai Hadas break; 125*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIS: 126*e662e14dSYishai Hadas obj_id = MLX5_GET(query_tis_in, in, tisn); 127*e662e14dSYishai Hadas break; 128*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIS: 129*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_tis_in, in, tisn); 130*e662e14dSYishai Hadas break; 131*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE: 132*e662e14dSYishai Hadas obj_id = MLX5_GET(query_flow_table_in, in, table_id); 133*e662e14dSYishai Hadas break; 134*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 135*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_flow_table_in, in, table_id); 136*e662e14dSYishai Hadas break; 137*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_GROUP: 138*e662e14dSYishai Hadas obj_id = MLX5_GET(query_flow_group_in, in, group_id); 139*e662e14dSYishai Hadas break; 140*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 141*e662e14dSYishai Hadas obj_id = MLX5_GET(query_fte_in, in, flow_index); 142*e662e14dSYishai Hadas break; 143*e662e14dSYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 144*e662e14dSYishai Hadas obj_id = MLX5_GET(set_fte_in, in, flow_index); 145*e662e14dSYishai Hadas break; 146*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_Q_COUNTER: 147*e662e14dSYishai Hadas obj_id = MLX5_GET(query_q_counter_in, in, counter_set_id); 148*e662e14dSYishai Hadas break; 149*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 150*e662e14dSYishai Hadas obj_id = MLX5_GET(query_flow_counter_in, in, flow_counter_id); 151*e662e14dSYishai Hadas break; 152*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 153*e662e14dSYishai Hadas obj_id = MLX5_GET(general_obj_in_cmd_hdr, in, obj_id); 154*e662e14dSYishai Hadas break; 155*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 156*e662e14dSYishai Hadas obj_id = MLX5_GET(query_scheduling_element_in, in, 157*e662e14dSYishai Hadas scheduling_element_id); 158*e662e14dSYishai Hadas break; 159*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 160*e662e14dSYishai Hadas obj_id = MLX5_GET(modify_scheduling_element_in, in, 161*e662e14dSYishai Hadas scheduling_element_id); 162*e662e14dSYishai Hadas break; 163*e662e14dSYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 164*e662e14dSYishai Hadas obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port); 165*e662e14dSYishai Hadas break; 166*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 167*e662e14dSYishai Hadas obj_id = MLX5_GET(query_l2_table_entry_in, in, table_index); 168*e662e14dSYishai Hadas break; 169*e662e14dSYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 170*e662e14dSYishai Hadas obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index); 171*e662e14dSYishai Hadas break; 172*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_QP: 173*e662e14dSYishai Hadas obj_id = MLX5_GET(query_qp_in, in, qpn); 174*e662e14dSYishai Hadas break; 175*e662e14dSYishai Hadas case MLX5_CMD_OP_RST2INIT_QP: 176*e662e14dSYishai Hadas obj_id = MLX5_GET(rst2init_qp_in, in, qpn); 177*e662e14dSYishai Hadas break; 178*e662e14dSYishai Hadas case MLX5_CMD_OP_INIT2RTR_QP: 179*e662e14dSYishai Hadas obj_id = MLX5_GET(init2rtr_qp_in, in, qpn); 180*e662e14dSYishai Hadas break; 181*e662e14dSYishai Hadas case MLX5_CMD_OP_RTR2RTS_QP: 182*e662e14dSYishai Hadas obj_id = MLX5_GET(rtr2rts_qp_in, in, qpn); 183*e662e14dSYishai Hadas break; 184*e662e14dSYishai Hadas case MLX5_CMD_OP_RTS2RTS_QP: 185*e662e14dSYishai Hadas obj_id = MLX5_GET(rts2rts_qp_in, in, qpn); 186*e662e14dSYishai Hadas break; 187*e662e14dSYishai Hadas case MLX5_CMD_OP_SQERR2RTS_QP: 188*e662e14dSYishai Hadas obj_id = MLX5_GET(sqerr2rts_qp_in, in, qpn); 189*e662e14dSYishai Hadas break; 190*e662e14dSYishai Hadas case MLX5_CMD_OP_2ERR_QP: 191*e662e14dSYishai Hadas obj_id = MLX5_GET(qp_2err_in, in, qpn); 192*e662e14dSYishai Hadas break; 193*e662e14dSYishai Hadas case MLX5_CMD_OP_2RST_QP: 194*e662e14dSYishai Hadas obj_id = MLX5_GET(qp_2rst_in, in, qpn); 195*e662e14dSYishai Hadas break; 196*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_DCT: 197*e662e14dSYishai Hadas obj_id = MLX5_GET(query_dct_in, in, dctn); 198*e662e14dSYishai Hadas break; 199*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRQ: 200*e662e14dSYishai Hadas obj_id = MLX5_GET(query_xrq_in, in, xrqn); 201*e662e14dSYishai Hadas break; 202*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRC_SRQ: 203*e662e14dSYishai Hadas obj_id = MLX5_GET(query_xrc_srq_in, in, xrc_srqn); 204*e662e14dSYishai Hadas break; 205*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRC_SRQ: 206*e662e14dSYishai Hadas obj_id = MLX5_GET(arm_xrc_srq_in, in, xrc_srqn); 207*e662e14dSYishai Hadas break; 208*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SRQ: 209*e662e14dSYishai Hadas obj_id = MLX5_GET(query_srq_in, in, srqn); 210*e662e14dSYishai Hadas break; 211*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_RQ: 212*e662e14dSYishai Hadas obj_id = MLX5_GET(arm_rq_in, in, srq_number); 213*e662e14dSYishai Hadas break; 214*e662e14dSYishai Hadas case MLX5_CMD_OP_DRAIN_DCT: 215*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 216*e662e14dSYishai Hadas obj_id = MLX5_GET(drain_dct_in, in, dctn); 217*e662e14dSYishai Hadas break; 218*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRQ: 219*e662e14dSYishai Hadas obj_id = MLX5_GET(arm_xrq_in, in, xrqn); 220*e662e14dSYishai Hadas break; 221*e662e14dSYishai Hadas default: 222*e662e14dSYishai Hadas return false; 223*e662e14dSYishai Hadas } 224*e662e14dSYishai Hadas 225*e662e14dSYishai Hadas if (obj_id == obj->obj_id) 226*e662e14dSYishai Hadas return true; 227*e662e14dSYishai Hadas 228*e662e14dSYishai Hadas return false; 229*e662e14dSYishai Hadas } 230*e662e14dSYishai Hadas 2317efce369SYishai Hadas static bool devx_is_obj_create_cmd(const void *in) 2327efce369SYishai Hadas { 2337efce369SYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 2347efce369SYishai Hadas 2357efce369SYishai Hadas switch (opcode) { 2367efce369SYishai Hadas case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 2377efce369SYishai Hadas case MLX5_CMD_OP_CREATE_MKEY: 2387efce369SYishai Hadas case MLX5_CMD_OP_CREATE_CQ: 2397efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_PD: 2407efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 2417efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RMP: 2427efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SQ: 2437efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQ: 2447efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQT: 2457efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIR: 2467efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIS: 2477efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_Q_COUNTER: 2487efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_TABLE: 2497efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_GROUP: 2507efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 2517efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_ENCAP_HEADER: 2527efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 2537efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 2547efce369SYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 2557efce369SYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 2567efce369SYishai Hadas case MLX5_CMD_OP_CREATE_QP: 2577efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SRQ: 2587efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRC_SRQ: 2597efce369SYishai Hadas case MLX5_CMD_OP_CREATE_DCT: 2607efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRQ: 2617efce369SYishai Hadas case MLX5_CMD_OP_ATTACH_TO_MCG: 2627efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_XRCD: 2637efce369SYishai Hadas return true; 2647efce369SYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 2657efce369SYishai Hadas { 2667efce369SYishai Hadas u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 2677efce369SYishai Hadas if (op_mod == 0) 2687efce369SYishai Hadas return true; 2697efce369SYishai Hadas return false; 2707efce369SYishai Hadas } 2717efce369SYishai Hadas default: 2727efce369SYishai Hadas return false; 2737efce369SYishai Hadas } 2747efce369SYishai Hadas } 2757efce369SYishai Hadas 276*e662e14dSYishai Hadas static bool devx_is_obj_modify_cmd(const void *in) 277*e662e14dSYishai Hadas { 278*e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 279*e662e14dSYishai Hadas 280*e662e14dSYishai Hadas switch (opcode) { 281*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 282*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_CQ: 283*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RMP: 284*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SQ: 285*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQ: 286*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQT: 287*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIR: 288*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIS: 289*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 290*e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 291*e662e14dSYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 292*e662e14dSYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 293*e662e14dSYishai Hadas case MLX5_CMD_OP_RST2INIT_QP: 294*e662e14dSYishai Hadas case MLX5_CMD_OP_INIT2RTR_QP: 295*e662e14dSYishai Hadas case MLX5_CMD_OP_RTR2RTS_QP: 296*e662e14dSYishai Hadas case MLX5_CMD_OP_RTS2RTS_QP: 297*e662e14dSYishai Hadas case MLX5_CMD_OP_SQERR2RTS_QP: 298*e662e14dSYishai Hadas case MLX5_CMD_OP_2ERR_QP: 299*e662e14dSYishai Hadas case MLX5_CMD_OP_2RST_QP: 300*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRC_SRQ: 301*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_RQ: 302*e662e14dSYishai Hadas case MLX5_CMD_OP_DRAIN_DCT: 303*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 304*e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRQ: 305*e662e14dSYishai Hadas return true; 306*e662e14dSYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 307*e662e14dSYishai Hadas { 308*e662e14dSYishai Hadas u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 309*e662e14dSYishai Hadas 310*e662e14dSYishai Hadas if (op_mod == 1) 311*e662e14dSYishai Hadas return true; 312*e662e14dSYishai Hadas return false; 313*e662e14dSYishai Hadas } 314*e662e14dSYishai Hadas default: 315*e662e14dSYishai Hadas return false; 316*e662e14dSYishai Hadas } 317*e662e14dSYishai Hadas } 318*e662e14dSYishai Hadas 319*e662e14dSYishai Hadas static bool devx_is_obj_query_cmd(const void *in) 320*e662e14dSYishai Hadas { 321*e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 322*e662e14dSYishai Hadas 323*e662e14dSYishai Hadas switch (opcode) { 324*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 325*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MKEY: 326*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_CQ: 327*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RMP: 328*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SQ: 329*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQ: 330*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQT: 331*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIR: 332*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIS: 333*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_Q_COUNTER: 334*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE: 335*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_GROUP: 336*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 337*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 338*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 339*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 340*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 341*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_QP: 342*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SRQ: 343*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRC_SRQ: 344*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_DCT: 345*e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRQ: 346*e662e14dSYishai Hadas return true; 347*e662e14dSYishai Hadas default: 348*e662e14dSYishai Hadas return false; 349*e662e14dSYishai Hadas } 350*e662e14dSYishai Hadas } 351*e662e14dSYishai Hadas 352*e662e14dSYishai Hadas static bool devx_is_general_cmd(void *in) 3538aa8c95cSYishai Hadas { 3548aa8c95cSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 3558aa8c95cSYishai Hadas 3568aa8c95cSYishai Hadas switch (opcode) { 3578aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_HCA_CAP: 3588aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VPORT_STATE: 3598aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ADAPTER: 3608aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ISSI: 3618aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT: 3628aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ROCE_ADDRESS: 3638aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VNIC_ENV: 3648aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VPORT_COUNTER: 3658aa8c95cSYishai Hadas case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG: 3668aa8c95cSYishai Hadas case MLX5_CMD_OP_NOP: 3678aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_STATUS: 3688aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_PARAMS: 3698aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_STATISTICS: 3708aa8c95cSYishai Hadas return true; 3718aa8c95cSYishai Hadas default: 3728aa8c95cSYishai Hadas return false; 3738aa8c95cSYishai Hadas } 3748aa8c95cSYishai Hadas } 3758aa8c95cSYishai Hadas 3768aa8c95cSYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)(struct ib_device *ib_dev, 3778aa8c95cSYishai Hadas struct ib_uverbs_file *file, 3788aa8c95cSYishai Hadas struct uverbs_attr_bundle *attrs) 3798aa8c95cSYishai Hadas { 3808aa8c95cSYishai Hadas struct mlx5_ib_ucontext *c = devx_ufile2uctx(file); 3818aa8c95cSYishai Hadas struct mlx5_ib_dev *dev = to_mdev(ib_dev); 3827efce369SYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr( 3837efce369SYishai Hadas attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN); 3848aa8c95cSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 3858aa8c95cSYishai Hadas MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT); 3868aa8c95cSYishai Hadas void *cmd_out; 3878aa8c95cSYishai Hadas int err; 3888aa8c95cSYishai Hadas 3898aa8c95cSYishai Hadas if (!c->devx_uid) 3908aa8c95cSYishai Hadas return -EPERM; 3918aa8c95cSYishai Hadas 3928aa8c95cSYishai Hadas /* Only white list of some general HCA commands are allowed for this method. */ 3938aa8c95cSYishai Hadas if (!devx_is_general_cmd(cmd_in)) 3948aa8c95cSYishai Hadas return -EINVAL; 3958aa8c95cSYishai Hadas 3968aa8c95cSYishai Hadas cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL); 3978aa8c95cSYishai Hadas if (!cmd_out) 3988aa8c95cSYishai Hadas return -ENOMEM; 3998aa8c95cSYishai Hadas 4008aa8c95cSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 4018aa8c95cSYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 4028aa8c95cSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN), 4038aa8c95cSYishai Hadas cmd_out, cmd_out_len); 4048aa8c95cSYishai Hadas if (err) 4058aa8c95cSYishai Hadas goto other_cmd_free; 4068aa8c95cSYishai Hadas 4078aa8c95cSYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out, cmd_out_len); 4088aa8c95cSYishai Hadas 4098aa8c95cSYishai Hadas other_cmd_free: 4108aa8c95cSYishai Hadas kvfree(cmd_out); 4118aa8c95cSYishai Hadas return err; 4128aa8c95cSYishai Hadas } 4138aa8c95cSYishai Hadas 4147efce369SYishai Hadas static void devx_obj_build_destroy_cmd(void *in, void *out, void *din, 4157efce369SYishai Hadas u32 *dinlen, 4167efce369SYishai Hadas u32 *obj_id) 4177efce369SYishai Hadas { 4187efce369SYishai Hadas u16 obj_type = MLX5_GET(general_obj_in_cmd_hdr, in, obj_type); 4197efce369SYishai Hadas u16 uid = MLX5_GET(general_obj_in_cmd_hdr, in, uid); 4207efce369SYishai Hadas 4217efce369SYishai Hadas *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 4227efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr); 4237efce369SYishai Hadas 4247efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, obj_id, *obj_id); 4257efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, uid, uid); 4267efce369SYishai Hadas 4277efce369SYishai Hadas switch (MLX5_GET(general_obj_in_cmd_hdr, in, opcode)) { 4287efce369SYishai Hadas case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 4297efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 4307efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, obj_type, obj_type); 4317efce369SYishai Hadas break; 4327efce369SYishai Hadas 4337efce369SYishai Hadas case MLX5_CMD_OP_CREATE_MKEY: 4347efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_MKEY); 4357efce369SYishai Hadas break; 4367efce369SYishai Hadas case MLX5_CMD_OP_CREATE_CQ: 4377efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_CQ); 4387efce369SYishai Hadas break; 4397efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_PD: 4407efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_PD); 4417efce369SYishai Hadas break; 4427efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 4437efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 4447efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN); 4457efce369SYishai Hadas break; 4467efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RMP: 4477efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RMP); 4487efce369SYishai Hadas break; 4497efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SQ: 4507efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SQ); 4517efce369SYishai Hadas break; 4527efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQ: 4537efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQ); 4547efce369SYishai Hadas break; 4557efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQT: 4567efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT); 4577efce369SYishai Hadas break; 4587efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIR: 4597efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIR); 4607efce369SYishai Hadas break; 4617efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIS: 4627efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS); 4637efce369SYishai Hadas break; 4647efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_Q_COUNTER: 4657efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 4667efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_Q_COUNTER); 4677efce369SYishai Hadas break; 4687efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_TABLE: 4697efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_table_in); 4707efce369SYishai Hadas *obj_id = MLX5_GET(create_flow_table_out, out, table_id); 4717efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, other_vport, 4727efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, other_vport)); 4737efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, vport_number, 4747efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, vport_number)); 4757efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, table_type, 4767efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, table_type)); 4777efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, table_id, *obj_id); 4787efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 4797efce369SYishai Hadas MLX5_CMD_OP_DESTROY_FLOW_TABLE); 4807efce369SYishai Hadas break; 4817efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_GROUP: 4827efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_group_in); 4837efce369SYishai Hadas *obj_id = MLX5_GET(create_flow_group_out, out, group_id); 4847efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, other_vport, 4857efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, other_vport)); 4867efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, vport_number, 4877efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, vport_number)); 4887efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, table_type, 4897efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, table_type)); 4907efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, table_id, 4917efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, table_id)); 4927efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, group_id, *obj_id); 4937efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 4947efce369SYishai Hadas MLX5_CMD_OP_DESTROY_FLOW_GROUP); 4957efce369SYishai Hadas break; 4967efce369SYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 4977efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_fte_in); 4987efce369SYishai Hadas *obj_id = MLX5_GET(set_fte_in, in, flow_index); 4997efce369SYishai Hadas MLX5_SET(delete_fte_in, din, other_vport, 5007efce369SYishai Hadas MLX5_GET(set_fte_in, in, other_vport)); 5017efce369SYishai Hadas MLX5_SET(delete_fte_in, din, vport_number, 5027efce369SYishai Hadas MLX5_GET(set_fte_in, in, vport_number)); 5037efce369SYishai Hadas MLX5_SET(delete_fte_in, din, table_type, 5047efce369SYishai Hadas MLX5_GET(set_fte_in, in, table_type)); 5057efce369SYishai Hadas MLX5_SET(delete_fte_in, din, table_id, 5067efce369SYishai Hadas MLX5_GET(set_fte_in, in, table_id)); 5077efce369SYishai Hadas MLX5_SET(delete_fte_in, din, flow_index, *obj_id); 5087efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5097efce369SYishai Hadas MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); 5107efce369SYishai Hadas break; 5117efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 5127efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5137efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_FLOW_COUNTER); 5147efce369SYishai Hadas break; 5157efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_ENCAP_HEADER: 5167efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5177efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_ENCAP_HEADER); 5187efce369SYishai Hadas break; 5197efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 5207efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5217efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT); 5227efce369SYishai Hadas break; 5237efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 5247efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_scheduling_element_in); 5257efce369SYishai Hadas *obj_id = MLX5_GET(create_scheduling_element_out, out, 5267efce369SYishai Hadas scheduling_element_id); 5277efce369SYishai Hadas MLX5_SET(destroy_scheduling_element_in, din, 5287efce369SYishai Hadas scheduling_hierarchy, 5297efce369SYishai Hadas MLX5_GET(create_scheduling_element_in, in, 5307efce369SYishai Hadas scheduling_hierarchy)); 5317efce369SYishai Hadas MLX5_SET(destroy_scheduling_element_in, din, 5327efce369SYishai Hadas scheduling_element_id, *obj_id); 5337efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5347efce369SYishai Hadas MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT); 5357efce369SYishai Hadas break; 5367efce369SYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 5377efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_vxlan_udp_dport_in); 5387efce369SYishai Hadas *obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port); 5397efce369SYishai Hadas MLX5_SET(delete_vxlan_udp_dport_in, din, vxlan_udp_port, *obj_id); 5407efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5417efce369SYishai Hadas MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT); 5427efce369SYishai Hadas break; 5437efce369SYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 5447efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_l2_table_entry_in); 5457efce369SYishai Hadas *obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index); 5467efce369SYishai Hadas MLX5_SET(delete_l2_table_entry_in, din, table_index, *obj_id); 5477efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5487efce369SYishai Hadas MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY); 5497efce369SYishai Hadas break; 5507efce369SYishai Hadas case MLX5_CMD_OP_CREATE_QP: 5517efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_QP); 5527efce369SYishai Hadas break; 5537efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SRQ: 5547efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SRQ); 5557efce369SYishai Hadas break; 5567efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRC_SRQ: 5577efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 5587efce369SYishai Hadas MLX5_CMD_OP_DESTROY_XRC_SRQ); 5597efce369SYishai Hadas break; 5607efce369SYishai Hadas case MLX5_CMD_OP_CREATE_DCT: 5617efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_DCT); 5627efce369SYishai Hadas break; 5637efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRQ: 5647efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_XRQ); 5657efce369SYishai Hadas break; 5667efce369SYishai Hadas case MLX5_CMD_OP_ATTACH_TO_MCG: 5677efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(detach_from_mcg_in); 5687efce369SYishai Hadas MLX5_SET(detach_from_mcg_in, din, qpn, 5697efce369SYishai Hadas MLX5_GET(attach_to_mcg_in, in, qpn)); 5707efce369SYishai Hadas memcpy(MLX5_ADDR_OF(detach_from_mcg_in, din, multicast_gid), 5717efce369SYishai Hadas MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid), 5727efce369SYishai Hadas MLX5_FLD_SZ_BYTES(attach_to_mcg_in, multicast_gid)); 5737efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DETACH_FROM_MCG); 5747efce369SYishai Hadas break; 5757efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_XRCD: 5767efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD); 5777efce369SYishai Hadas break; 5787efce369SYishai Hadas default: 5797efce369SYishai Hadas /* The entry must match to one of the devx_is_obj_create_cmd */ 5807efce369SYishai Hadas WARN_ON(true); 5817efce369SYishai Hadas break; 5827efce369SYishai Hadas } 5837efce369SYishai Hadas } 5847efce369SYishai Hadas 5857efce369SYishai Hadas static int devx_obj_cleanup(struct ib_uobject *uobject, 5867efce369SYishai Hadas enum rdma_remove_reason why) 5877efce369SYishai Hadas { 5887efce369SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 5897efce369SYishai Hadas struct devx_obj *obj = uobject->object; 5907efce369SYishai Hadas int ret; 5917efce369SYishai Hadas 5927efce369SYishai Hadas ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out)); 5937efce369SYishai Hadas if (ret && why == RDMA_REMOVE_DESTROY) 5947efce369SYishai Hadas return ret; 5957efce369SYishai Hadas 5967efce369SYishai Hadas kfree(obj); 5977efce369SYishai Hadas return ret; 5987efce369SYishai Hadas } 5997efce369SYishai Hadas 6007efce369SYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_DESTROY)(struct ib_device *ib_dev, 6017efce369SYishai Hadas struct ib_uverbs_file *file, 6027efce369SYishai Hadas struct uverbs_attr_bundle *attrs) 6037efce369SYishai Hadas { 6047efce369SYishai Hadas return 0; 6057efce369SYishai Hadas } 6067efce369SYishai Hadas 6077efce369SYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(struct ib_device *ib_dev, 6087efce369SYishai Hadas struct ib_uverbs_file *file, 6097efce369SYishai Hadas struct uverbs_attr_bundle *attrs) 6107efce369SYishai Hadas { 6117efce369SYishai Hadas struct mlx5_ib_ucontext *c = devx_ufile2uctx(file); 6127efce369SYishai Hadas struct mlx5_ib_dev *dev = to_mdev(ib_dev); 6137efce369SYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN); 6147efce369SYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 6157efce369SYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT); 6167efce369SYishai Hadas void *cmd_out; 6177efce369SYishai Hadas struct ib_uobject *uobj; 6187efce369SYishai Hadas struct devx_obj *obj; 6197efce369SYishai Hadas int err; 6207efce369SYishai Hadas 6217efce369SYishai Hadas if (!c->devx_uid) 6227efce369SYishai Hadas return -EPERM; 6237efce369SYishai Hadas 6247efce369SYishai Hadas if (!devx_is_obj_create_cmd(cmd_in)) 6257efce369SYishai Hadas return -EINVAL; 6267efce369SYishai Hadas 6277efce369SYishai Hadas obj = kzalloc(sizeof(struct devx_obj), GFP_KERNEL); 6287efce369SYishai Hadas if (!obj) 6297efce369SYishai Hadas return -ENOMEM; 6307efce369SYishai Hadas 6317efce369SYishai Hadas cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL); 6327efce369SYishai Hadas if (!cmd_out) { 6337efce369SYishai Hadas err = -ENOMEM; 6347efce369SYishai Hadas goto obj_free; 6357efce369SYishai Hadas } 6367efce369SYishai Hadas 6377efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 6387efce369SYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 6397efce369SYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN), 6407efce369SYishai Hadas cmd_out, cmd_out_len); 6417efce369SYishai Hadas if (err) 6427efce369SYishai Hadas goto cmd_free; 6437efce369SYishai Hadas 6447efce369SYishai Hadas uobj = uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE); 6457efce369SYishai Hadas uobj->object = obj; 6467efce369SYishai Hadas obj->mdev = dev->mdev; 6477efce369SYishai Hadas devx_obj_build_destroy_cmd(cmd_in, cmd_out, obj->dinbox, &obj->dinlen, &obj->obj_id); 6487efce369SYishai Hadas WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32)); 6497efce369SYishai Hadas 6507efce369SYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len); 6517efce369SYishai Hadas if (err) 6527efce369SYishai Hadas goto cmd_free; 6537efce369SYishai Hadas 6547efce369SYishai Hadas kvfree(cmd_out); 6557efce369SYishai Hadas return 0; 6567efce369SYishai Hadas 6577efce369SYishai Hadas cmd_free: 6587efce369SYishai Hadas kvfree(cmd_out); 6597efce369SYishai Hadas obj_free: 6607efce369SYishai Hadas kfree(obj); 6617efce369SYishai Hadas return err; 6627efce369SYishai Hadas } 6637efce369SYishai Hadas 664*e662e14dSYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MODIFY)(struct ib_device *ib_dev, 665*e662e14dSYishai Hadas struct ib_uverbs_file *file, 666*e662e14dSYishai Hadas struct uverbs_attr_bundle *attrs) 667*e662e14dSYishai Hadas { 668*e662e14dSYishai Hadas struct mlx5_ib_ucontext *c = devx_ufile2uctx(file); 669*e662e14dSYishai Hadas struct mlx5_ib_dev *dev = to_mdev(ib_dev); 670*e662e14dSYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN); 671*e662e14dSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 672*e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT); 673*e662e14dSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 674*e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE); 675*e662e14dSYishai Hadas void *cmd_out; 676*e662e14dSYishai Hadas int err; 677*e662e14dSYishai Hadas 678*e662e14dSYishai Hadas if (!c->devx_uid) 679*e662e14dSYishai Hadas return -EPERM; 680*e662e14dSYishai Hadas 681*e662e14dSYishai Hadas if (!devx_is_obj_modify_cmd(cmd_in)) 682*e662e14dSYishai Hadas return -EINVAL; 683*e662e14dSYishai Hadas 684*e662e14dSYishai Hadas if (!devx_is_valid_obj_id(uobj->object, cmd_in)) 685*e662e14dSYishai Hadas return -EINVAL; 686*e662e14dSYishai Hadas 687*e662e14dSYishai Hadas cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL); 688*e662e14dSYishai Hadas if (!cmd_out) 689*e662e14dSYishai Hadas return -ENOMEM; 690*e662e14dSYishai Hadas 691*e662e14dSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 692*e662e14dSYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 693*e662e14dSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN), 694*e662e14dSYishai Hadas cmd_out, cmd_out_len); 695*e662e14dSYishai Hadas if (err) 696*e662e14dSYishai Hadas goto other_cmd_free; 697*e662e14dSYishai Hadas 698*e662e14dSYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 699*e662e14dSYishai Hadas cmd_out, cmd_out_len); 700*e662e14dSYishai Hadas 701*e662e14dSYishai Hadas other_cmd_free: 702*e662e14dSYishai Hadas kvfree(cmd_out); 703*e662e14dSYishai Hadas return err; 704*e662e14dSYishai Hadas } 705*e662e14dSYishai Hadas 706*e662e14dSYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)(struct ib_device *ib_dev, 707*e662e14dSYishai Hadas struct ib_uverbs_file *file, 708*e662e14dSYishai Hadas struct uverbs_attr_bundle *attrs) 709*e662e14dSYishai Hadas { 710*e662e14dSYishai Hadas struct mlx5_ib_ucontext *c = devx_ufile2uctx(file); 711*e662e14dSYishai Hadas struct mlx5_ib_dev *dev = to_mdev(ib_dev); 712*e662e14dSYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN); 713*e662e14dSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 714*e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT); 715*e662e14dSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 716*e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE); 717*e662e14dSYishai Hadas void *cmd_out; 718*e662e14dSYishai Hadas int err; 719*e662e14dSYishai Hadas 720*e662e14dSYishai Hadas if (!c->devx_uid) 721*e662e14dSYishai Hadas return -EPERM; 722*e662e14dSYishai Hadas 723*e662e14dSYishai Hadas if (!devx_is_obj_query_cmd(cmd_in)) 724*e662e14dSYishai Hadas return -EINVAL; 725*e662e14dSYishai Hadas 726*e662e14dSYishai Hadas if (!devx_is_valid_obj_id(uobj->object, cmd_in)) 727*e662e14dSYishai Hadas return -EINVAL; 728*e662e14dSYishai Hadas 729*e662e14dSYishai Hadas cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL); 730*e662e14dSYishai Hadas if (!cmd_out) 731*e662e14dSYishai Hadas return -ENOMEM; 732*e662e14dSYishai Hadas 733*e662e14dSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, c->devx_uid); 734*e662e14dSYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 735*e662e14dSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN), 736*e662e14dSYishai Hadas cmd_out, cmd_out_len); 737*e662e14dSYishai Hadas if (err) 738*e662e14dSYishai Hadas goto other_cmd_free; 739*e662e14dSYishai Hadas 740*e662e14dSYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, cmd_out, cmd_out_len); 741*e662e14dSYishai Hadas 742*e662e14dSYishai Hadas other_cmd_free: 743*e662e14dSYishai Hadas kvfree(cmd_out); 744*e662e14dSYishai Hadas return err; 745*e662e14dSYishai Hadas } 746*e662e14dSYishai Hadas 7478aa8c95cSYishai Hadas static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OTHER, 7488aa8c95cSYishai Hadas &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN, 7498aa8c95cSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 7508aa8c95cSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 7518aa8c95cSYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO | 7528aa8c95cSYishai Hadas UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)), 7538aa8c95cSYishai Hadas &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, 7548aa8c95cSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 7558aa8c95cSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 7568aa8c95cSYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)) 7578aa8c95cSYishai Hadas ); 7588aa8c95cSYishai Hadas 7597efce369SYishai Hadas static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE, 7607efce369SYishai Hadas &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE, 7617efce369SYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 7627efce369SYishai Hadas UVERBS_ACCESS_NEW, 7637efce369SYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)), 7647efce369SYishai Hadas &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN, 7657efce369SYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 7667efce369SYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 7677efce369SYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO | 7687efce369SYishai Hadas UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)), 7697efce369SYishai Hadas &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, 7707efce369SYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 7717efce369SYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 7727efce369SYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))); 7737efce369SYishai Hadas 7747efce369SYishai Hadas static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY, 7757efce369SYishai Hadas &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE, 7767efce369SYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 7777efce369SYishai Hadas UVERBS_ACCESS_DESTROY, 7787efce369SYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY))); 7797efce369SYishai Hadas 780*e662e14dSYishai Hadas static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY, 781*e662e14dSYishai Hadas &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE, 782*e662e14dSYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 783*e662e14dSYishai Hadas UVERBS_ACCESS_WRITE, 784*e662e14dSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)), 785*e662e14dSYishai Hadas &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, 786*e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 787*e662e14dSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 788*e662e14dSYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO | 789*e662e14dSYishai Hadas UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)), 790*e662e14dSYishai Hadas &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 791*e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 792*e662e14dSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 793*e662e14dSYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))); 794*e662e14dSYishai Hadas 795*e662e14dSYishai Hadas static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY, 796*e662e14dSYishai Hadas &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE, 797*e662e14dSYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 798*e662e14dSYishai Hadas UVERBS_ACCESS_READ, 799*e662e14dSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)), 800*e662e14dSYishai Hadas &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, 801*e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 802*e662e14dSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 803*e662e14dSYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO | 804*e662e14dSYishai Hadas UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)), 805*e662e14dSYishai Hadas &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, 806*e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 807*e662e14dSYishai Hadas UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY | 808*e662e14dSYishai Hadas UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))); 809*e662e14dSYishai Hadas 8108aa8c95cSYishai Hadas static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX, 8118aa8c95cSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER)); 8128aa8c95cSYishai Hadas 8137efce369SYishai Hadas static DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ, 8147efce369SYishai Hadas &UVERBS_TYPE_ALLOC_IDR(0, devx_obj_cleanup), 8157efce369SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE), 816*e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY), 817*e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY), 818*e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY)); 8197efce369SYishai Hadas 8208aa8c95cSYishai Hadas static DECLARE_UVERBS_OBJECT_TREE(devx_objects, 8217efce369SYishai Hadas &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX), 8227efce369SYishai Hadas &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ)); 823