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> 11a124edbaSYishai Hadas #include <rdma/mlx5_user_ioctl_verbs.h> 12a8b92ca1SYishai Hadas #include <rdma/ib_umem.h> 1334613eb1SYishai Hadas #include <rdma/uverbs_std_types.h> 14a8b92ca1SYishai Hadas #include <linux/mlx5/driver.h> 15a8b92ca1SYishai Hadas #include <linux/mlx5/fs.h> 16a8b92ca1SYishai Hadas #include "mlx5_ib.h" 17a8b92ca1SYishai Hadas 188aa8c95cSYishai Hadas #define UVERBS_MODULE_NAME mlx5_ib 198aa8c95cSYishai Hadas #include <rdma/uverbs_named_ioctl.h> 208aa8c95cSYishai Hadas 21534fd7aaSYishai Hadas enum devx_obj_flags { 22534fd7aaSYishai Hadas DEVX_OBJ_FLAGS_INDIRECT_MKEY = 1 << 0, 23*c5ae1954SYishai Hadas DEVX_OBJ_FLAGS_DCT = 1 << 1, 24534fd7aaSYishai Hadas }; 25534fd7aaSYishai Hadas 26a124edbaSYishai Hadas struct devx_async_data { 27a124edbaSYishai Hadas struct mlx5_ib_dev *mdev; 28a124edbaSYishai Hadas struct list_head list; 29a124edbaSYishai Hadas struct ib_uobject *fd_uobj; 30a124edbaSYishai Hadas struct mlx5_async_work cb_work; 31a124edbaSYishai Hadas u16 cmd_out_len; 32a124edbaSYishai Hadas /* must be last field in this structure */ 33a124edbaSYishai Hadas struct mlx5_ib_uapi_devx_async_cmd_hdr hdr; 34a124edbaSYishai Hadas }; 35a124edbaSYishai Hadas 367efce369SYishai Hadas #define MLX5_MAX_DESTROY_INBOX_SIZE_DW MLX5_ST_SZ_DW(delete_fte_in) 377efce369SYishai Hadas struct devx_obj { 387efce369SYishai Hadas struct mlx5_core_dev *mdev; 392351776eSYishai Hadas u64 obj_id; 407efce369SYishai Hadas u32 dinlen; /* destroy inbox length */ 417efce369SYishai Hadas u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW]; 42534fd7aaSYishai Hadas u32 flags; 43*c5ae1954SYishai Hadas union { 44534fd7aaSYishai Hadas struct mlx5_ib_devx_mr devx_mr; 45*c5ae1954SYishai Hadas struct mlx5_core_dct core_dct; 46*c5ae1954SYishai Hadas }; 477efce369SYishai Hadas }; 487efce369SYishai Hadas 49aeae9457SYishai Hadas struct devx_umem { 50aeae9457SYishai Hadas struct mlx5_core_dev *mdev; 51aeae9457SYishai Hadas struct ib_umem *umem; 52aeae9457SYishai Hadas u32 page_offset; 53aeae9457SYishai Hadas int page_shift; 54aeae9457SYishai Hadas int ncont; 55aeae9457SYishai Hadas u32 dinlen; 56aeae9457SYishai Hadas u32 dinbox[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)]; 57aeae9457SYishai Hadas }; 58aeae9457SYishai Hadas 59aeae9457SYishai Hadas struct devx_umem_reg_cmd { 60aeae9457SYishai Hadas void *in; 61aeae9457SYishai Hadas u32 inlen; 62aeae9457SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 63aeae9457SYishai Hadas }; 64aeae9457SYishai Hadas 6515a1b4beSJason Gunthorpe static struct mlx5_ib_ucontext * 6615a1b4beSJason Gunthorpe devx_ufile2uctx(const struct uverbs_attr_bundle *attrs) 678aa8c95cSYishai Hadas { 6815a1b4beSJason Gunthorpe return to_mucontext(ib_uverbs_get_ucontext(attrs)); 698aa8c95cSYishai Hadas } 708aa8c95cSYishai Hadas 71fb98153bSYishai Hadas int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user) 72a8b92ca1SYishai Hadas { 73a8b92ca1SYishai Hadas u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0}; 74a8b92ca1SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 756e3722baSYishai Hadas void *uctx; 76a8b92ca1SYishai Hadas int err; 7776dc5a84SYishai Hadas u16 uid; 78fb98153bSYishai Hadas u32 cap = 0; 79a8b92ca1SYishai Hadas 806e3722baSYishai Hadas /* 0 means not supported */ 816e3722baSYishai Hadas if (!MLX5_CAP_GEN(dev->mdev, log_max_uctx)) 82a8b92ca1SYishai Hadas return -EINVAL; 83a8b92ca1SYishai Hadas 846e3722baSYishai Hadas uctx = MLX5_ADDR_OF(create_uctx_in, in, uctx); 85fb98153bSYishai Hadas if (is_user && capable(CAP_NET_RAW) && 86fb98153bSYishai Hadas (MLX5_CAP_GEN(dev->mdev, uctx_cap) & MLX5_UCTX_CAP_RAW_TX)) 87fb98153bSYishai Hadas cap |= MLX5_UCTX_CAP_RAW_TX; 88fb98153bSYishai Hadas 896e3722baSYishai Hadas MLX5_SET(create_uctx_in, in, opcode, MLX5_CMD_OP_CREATE_UCTX); 90fb98153bSYishai Hadas MLX5_SET(uctx, uctx, cap, cap); 91a8b92ca1SYishai Hadas 92a8b92ca1SYishai Hadas err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 93a8b92ca1SYishai Hadas if (err) 94a8b92ca1SYishai Hadas return err; 95a8b92ca1SYishai Hadas 9676dc5a84SYishai Hadas uid = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 9776dc5a84SYishai Hadas return uid; 98a8b92ca1SYishai Hadas } 99a8b92ca1SYishai Hadas 10076dc5a84SYishai Hadas void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid) 101a8b92ca1SYishai Hadas { 1026e3722baSYishai Hadas u32 in[MLX5_ST_SZ_DW(destroy_uctx_in)] = {0}; 103a8b92ca1SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 104a8b92ca1SYishai Hadas 1056e3722baSYishai Hadas MLX5_SET(destroy_uctx_in, in, opcode, MLX5_CMD_OP_DESTROY_UCTX); 1066e3722baSYishai Hadas MLX5_SET(destroy_uctx_in, in, uid, uid); 107a8b92ca1SYishai Hadas 108a8b92ca1SYishai Hadas mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 109a8b92ca1SYishai Hadas } 1108aa8c95cSYishai Hadas 11132269441SYishai Hadas bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type) 11232269441SYishai Hadas { 11332269441SYishai Hadas struct devx_obj *devx_obj = obj; 11432269441SYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode); 11532269441SYishai Hadas 11632269441SYishai Hadas switch (opcode) { 11732269441SYishai Hadas case MLX5_CMD_OP_DESTROY_TIR: 11832269441SYishai Hadas *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR; 11932269441SYishai Hadas *dest_id = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, 12032269441SYishai Hadas obj_id); 12132269441SYishai Hadas return true; 12232269441SYishai Hadas 12332269441SYishai Hadas case MLX5_CMD_OP_DESTROY_FLOW_TABLE: 12432269441SYishai Hadas *dest_type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 12532269441SYishai Hadas *dest_id = MLX5_GET(destroy_flow_table_in, devx_obj->dinbox, 12632269441SYishai Hadas table_id); 12732269441SYishai Hadas return true; 12832269441SYishai Hadas default: 12932269441SYishai Hadas return false; 13032269441SYishai Hadas } 13132269441SYishai Hadas } 13232269441SYishai Hadas 133bfc5d839SMark Bloch bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id) 134bfc5d839SMark Bloch { 135bfc5d839SMark Bloch struct devx_obj *devx_obj = obj; 136bfc5d839SMark Bloch u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode); 137bfc5d839SMark Bloch 138bfc5d839SMark Bloch if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) { 139bfc5d839SMark Bloch *counter_id = MLX5_GET(dealloc_flow_counter_in, 140bfc5d839SMark Bloch devx_obj->dinbox, 141bfc5d839SMark Bloch flow_counter_id); 142bfc5d839SMark Bloch return true; 143bfc5d839SMark Bloch } 144bfc5d839SMark Bloch 145bfc5d839SMark Bloch return false; 146bfc5d839SMark Bloch } 147bfc5d839SMark Bloch 1482351776eSYishai Hadas /* 1492351776eSYishai Hadas * As the obj_id in the firmware is not globally unique the object type 1502351776eSYishai Hadas * must be considered upon checking for a valid object id. 1512351776eSYishai Hadas * For that the opcode of the creator command is encoded as part of the obj_id. 1522351776eSYishai Hadas */ 1532351776eSYishai Hadas static u64 get_enc_obj_id(u16 opcode, u32 obj_id) 1542351776eSYishai Hadas { 1552351776eSYishai Hadas return ((u64)opcode << 32) | obj_id; 1562351776eSYishai Hadas } 1572351776eSYishai Hadas 15834613eb1SYishai Hadas static u64 devx_get_obj_id(const void *in) 159e662e14dSYishai Hadas { 160e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 1612351776eSYishai Hadas u64 obj_id; 162e662e14dSYishai Hadas 163e662e14dSYishai Hadas switch (opcode) { 164e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 165e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 1662351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_GENERAL_OBJECT, 1672351776eSYishai Hadas MLX5_GET(general_obj_in_cmd_hdr, in, 1682351776eSYishai Hadas obj_id)); 169e662e14dSYishai Hadas break; 170e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MKEY: 1712351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_MKEY, 1722351776eSYishai Hadas MLX5_GET(query_mkey_in, in, 1732351776eSYishai Hadas mkey_index)); 174e662e14dSYishai Hadas break; 175e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_CQ: 1762351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ, 1772351776eSYishai Hadas MLX5_GET(query_cq_in, in, cqn)); 178e662e14dSYishai Hadas break; 179e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_CQ: 1802351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ, 1812351776eSYishai Hadas MLX5_GET(modify_cq_in, in, cqn)); 182e662e14dSYishai Hadas break; 183e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SQ: 1842351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ, 1852351776eSYishai Hadas MLX5_GET(query_sq_in, in, sqn)); 186e662e14dSYishai Hadas break; 187e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SQ: 1882351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ, 1892351776eSYishai Hadas MLX5_GET(modify_sq_in, in, sqn)); 190e662e14dSYishai Hadas break; 191e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQ: 1922351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 1932351776eSYishai Hadas MLX5_GET(query_rq_in, in, rqn)); 194e662e14dSYishai Hadas break; 195e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQ: 1962351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 1972351776eSYishai Hadas MLX5_GET(modify_rq_in, in, rqn)); 198e662e14dSYishai Hadas break; 199e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RMP: 2002351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP, 2012351776eSYishai Hadas MLX5_GET(query_rmp_in, in, rmpn)); 202e662e14dSYishai Hadas break; 203e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RMP: 2042351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP, 2052351776eSYishai Hadas MLX5_GET(modify_rmp_in, in, rmpn)); 206e662e14dSYishai Hadas break; 207e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQT: 2082351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT, 2092351776eSYishai Hadas MLX5_GET(query_rqt_in, in, rqtn)); 210e662e14dSYishai Hadas break; 211e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQT: 2122351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT, 2132351776eSYishai Hadas MLX5_GET(modify_rqt_in, in, rqtn)); 214e662e14dSYishai Hadas break; 215e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIR: 2162351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR, 2172351776eSYishai Hadas MLX5_GET(query_tir_in, in, tirn)); 218e662e14dSYishai Hadas break; 219e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIR: 2202351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR, 2212351776eSYishai Hadas MLX5_GET(modify_tir_in, in, tirn)); 222e662e14dSYishai Hadas break; 223e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIS: 2242351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS, 2252351776eSYishai Hadas MLX5_GET(query_tis_in, in, tisn)); 226e662e14dSYishai Hadas break; 227e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIS: 2282351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS, 2292351776eSYishai Hadas MLX5_GET(modify_tis_in, in, tisn)); 230e662e14dSYishai Hadas break; 231e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE: 2322351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE, 2332351776eSYishai Hadas MLX5_GET(query_flow_table_in, in, 2342351776eSYishai Hadas table_id)); 235e662e14dSYishai Hadas break; 236e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 2372351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE, 2382351776eSYishai Hadas MLX5_GET(modify_flow_table_in, in, 2392351776eSYishai Hadas table_id)); 240e662e14dSYishai Hadas break; 241e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_GROUP: 2422351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_GROUP, 2432351776eSYishai Hadas MLX5_GET(query_flow_group_in, in, 2442351776eSYishai Hadas group_id)); 245e662e14dSYishai Hadas break; 246e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 2472351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY, 2482351776eSYishai Hadas MLX5_GET(query_fte_in, in, 2492351776eSYishai Hadas flow_index)); 250e662e14dSYishai Hadas break; 251e662e14dSYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 2522351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY, 2532351776eSYishai Hadas MLX5_GET(set_fte_in, in, flow_index)); 254e662e14dSYishai Hadas break; 255e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_Q_COUNTER: 2562351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_Q_COUNTER, 2572351776eSYishai Hadas MLX5_GET(query_q_counter_in, in, 2582351776eSYishai Hadas counter_set_id)); 259e662e14dSYishai Hadas break; 260e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 2612351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_FLOW_COUNTER, 2622351776eSYishai Hadas MLX5_GET(query_flow_counter_in, in, 2632351776eSYishai Hadas flow_counter_id)); 264e662e14dSYishai Hadas break; 265e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 2662351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT, 2672351776eSYishai Hadas MLX5_GET(general_obj_in_cmd_hdr, in, 2682351776eSYishai Hadas obj_id)); 269e662e14dSYishai Hadas break; 270e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 2712351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT, 2722351776eSYishai Hadas MLX5_GET(query_scheduling_element_in, 2732351776eSYishai Hadas in, scheduling_element_id)); 274e662e14dSYishai Hadas break; 275e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 2762351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT, 2772351776eSYishai Hadas MLX5_GET(modify_scheduling_element_in, 2782351776eSYishai Hadas in, scheduling_element_id)); 279e662e14dSYishai Hadas break; 280e662e14dSYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 2812351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT, 2822351776eSYishai Hadas MLX5_GET(add_vxlan_udp_dport_in, in, 2832351776eSYishai Hadas vxlan_udp_port)); 284e662e14dSYishai Hadas break; 285e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 2862351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY, 2872351776eSYishai Hadas MLX5_GET(query_l2_table_entry_in, in, 2882351776eSYishai Hadas table_index)); 289e662e14dSYishai Hadas break; 290e662e14dSYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 2912351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY, 2922351776eSYishai Hadas MLX5_GET(set_l2_table_entry_in, in, 2932351776eSYishai Hadas table_index)); 294e662e14dSYishai Hadas break; 295e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_QP: 2962351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 2972351776eSYishai Hadas MLX5_GET(query_qp_in, in, qpn)); 298e662e14dSYishai Hadas break; 299e662e14dSYishai Hadas case MLX5_CMD_OP_RST2INIT_QP: 3002351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 3012351776eSYishai Hadas MLX5_GET(rst2init_qp_in, in, qpn)); 302e662e14dSYishai Hadas break; 303e662e14dSYishai Hadas case MLX5_CMD_OP_INIT2RTR_QP: 3042351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 3052351776eSYishai Hadas MLX5_GET(init2rtr_qp_in, in, qpn)); 306e662e14dSYishai Hadas break; 307e662e14dSYishai Hadas case MLX5_CMD_OP_RTR2RTS_QP: 3082351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 3092351776eSYishai Hadas MLX5_GET(rtr2rts_qp_in, in, qpn)); 310e662e14dSYishai Hadas break; 311e662e14dSYishai Hadas case MLX5_CMD_OP_RTS2RTS_QP: 3122351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 3132351776eSYishai Hadas MLX5_GET(rts2rts_qp_in, in, qpn)); 314e662e14dSYishai Hadas break; 315e662e14dSYishai Hadas case MLX5_CMD_OP_SQERR2RTS_QP: 3162351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 3172351776eSYishai Hadas MLX5_GET(sqerr2rts_qp_in, in, qpn)); 318e662e14dSYishai Hadas break; 319e662e14dSYishai Hadas case MLX5_CMD_OP_2ERR_QP: 3202351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 3212351776eSYishai Hadas MLX5_GET(qp_2err_in, in, qpn)); 322e662e14dSYishai Hadas break; 323e662e14dSYishai Hadas case MLX5_CMD_OP_2RST_QP: 3242351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 3252351776eSYishai Hadas MLX5_GET(qp_2rst_in, in, qpn)); 326e662e14dSYishai Hadas break; 327e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_DCT: 3282351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT, 3292351776eSYishai Hadas MLX5_GET(query_dct_in, in, dctn)); 330e662e14dSYishai Hadas break; 331e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRQ: 332719598c9SYishai Hadas case MLX5_CMD_OP_QUERY_XRQ_DC_PARAMS_ENTRY: 333719598c9SYishai Hadas case MLX5_CMD_OP_QUERY_XRQ_ERROR_PARAMS: 3342351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ, 3352351776eSYishai Hadas MLX5_GET(query_xrq_in, in, xrqn)); 336e662e14dSYishai Hadas break; 337e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRC_SRQ: 3382351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ, 3392351776eSYishai Hadas MLX5_GET(query_xrc_srq_in, in, 3402351776eSYishai Hadas xrc_srqn)); 341e662e14dSYishai Hadas break; 342e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRC_SRQ: 3432351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ, 3442351776eSYishai Hadas MLX5_GET(arm_xrc_srq_in, in, xrc_srqn)); 345e662e14dSYishai Hadas break; 346e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SRQ: 3472351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SRQ, 3482351776eSYishai Hadas MLX5_GET(query_srq_in, in, srqn)); 349e662e14dSYishai Hadas break; 350e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_RQ: 3512351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 3522351776eSYishai Hadas MLX5_GET(arm_rq_in, in, srq_number)); 353e662e14dSYishai Hadas break; 354e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 3552351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT, 3562351776eSYishai Hadas MLX5_GET(drain_dct_in, in, dctn)); 357e662e14dSYishai Hadas break; 358e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRQ: 359719598c9SYishai Hadas case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY: 3602351776eSYishai Hadas obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ, 3612351776eSYishai Hadas MLX5_GET(arm_xrq_in, in, xrqn)); 362e662e14dSYishai Hadas break; 363719598c9SYishai Hadas case MLX5_CMD_OP_QUERY_PACKET_REFORMAT_CONTEXT: 364719598c9SYishai Hadas obj_id = get_enc_obj_id 365719598c9SYishai Hadas (MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT, 366719598c9SYishai Hadas MLX5_GET(query_packet_reformat_context_in, 367719598c9SYishai Hadas in, packet_reformat_id)); 368719598c9SYishai Hadas break; 369e662e14dSYishai Hadas default: 37034613eb1SYishai Hadas obj_id = 0; 371e662e14dSYishai Hadas } 372e662e14dSYishai Hadas 37334613eb1SYishai Hadas return obj_id; 37434613eb1SYishai Hadas } 375e662e14dSYishai Hadas 37634613eb1SYishai Hadas static bool devx_is_valid_obj_id(struct ib_uobject *uobj, const void *in) 37734613eb1SYishai Hadas { 37834613eb1SYishai Hadas u64 obj_id = devx_get_obj_id(in); 37934613eb1SYishai Hadas 38034613eb1SYishai Hadas if (!obj_id) 381e662e14dSYishai Hadas return false; 38234613eb1SYishai Hadas 38334613eb1SYishai Hadas switch (uobj_get_object_id(uobj)) { 38434613eb1SYishai Hadas case UVERBS_OBJECT_CQ: 38534613eb1SYishai Hadas return get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ, 38634613eb1SYishai Hadas to_mcq(uobj->object)->mcq.cqn) == 38734613eb1SYishai Hadas obj_id; 38834613eb1SYishai Hadas 38934613eb1SYishai Hadas case UVERBS_OBJECT_SRQ: 39034613eb1SYishai Hadas { 39134613eb1SYishai Hadas struct mlx5_core_srq *srq = &(to_msrq(uobj->object)->msrq); 39234613eb1SYishai Hadas struct mlx5_ib_dev *dev = to_mdev(uobj->context->device); 39334613eb1SYishai Hadas u16 opcode; 39434613eb1SYishai Hadas 39534613eb1SYishai Hadas switch (srq->common.res) { 39634613eb1SYishai Hadas case MLX5_RES_XSRQ: 39734613eb1SYishai Hadas opcode = MLX5_CMD_OP_CREATE_XRC_SRQ; 39834613eb1SYishai Hadas break; 39934613eb1SYishai Hadas case MLX5_RES_XRQ: 40034613eb1SYishai Hadas opcode = MLX5_CMD_OP_CREATE_XRQ; 40134613eb1SYishai Hadas break; 40234613eb1SYishai Hadas default: 40334613eb1SYishai Hadas if (!dev->mdev->issi) 40434613eb1SYishai Hadas opcode = MLX5_CMD_OP_CREATE_SRQ; 40534613eb1SYishai Hadas else 40634613eb1SYishai Hadas opcode = MLX5_CMD_OP_CREATE_RMP; 40734613eb1SYishai Hadas } 40834613eb1SYishai Hadas 40934613eb1SYishai Hadas return get_enc_obj_id(opcode, 41034613eb1SYishai Hadas to_msrq(uobj->object)->msrq.srqn) == 41134613eb1SYishai Hadas obj_id; 41234613eb1SYishai Hadas } 41334613eb1SYishai Hadas 41434613eb1SYishai Hadas case UVERBS_OBJECT_QP: 41534613eb1SYishai Hadas { 41634613eb1SYishai Hadas struct mlx5_ib_qp *qp = to_mqp(uobj->object); 41734613eb1SYishai Hadas enum ib_qp_type qp_type = qp->ibqp.qp_type; 41834613eb1SYishai Hadas 41934613eb1SYishai Hadas if (qp_type == IB_QPT_RAW_PACKET || 42034613eb1SYishai Hadas (qp->flags & MLX5_IB_QP_UNDERLAY)) { 42134613eb1SYishai Hadas struct mlx5_ib_raw_packet_qp *raw_packet_qp = 42234613eb1SYishai Hadas &qp->raw_packet_qp; 42334613eb1SYishai Hadas struct mlx5_ib_rq *rq = &raw_packet_qp->rq; 42434613eb1SYishai Hadas struct mlx5_ib_sq *sq = &raw_packet_qp->sq; 42534613eb1SYishai Hadas 42634613eb1SYishai Hadas return (get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 42734613eb1SYishai Hadas rq->base.mqp.qpn) == obj_id || 42834613eb1SYishai Hadas get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ, 42934613eb1SYishai Hadas sq->base.mqp.qpn) == obj_id || 43034613eb1SYishai Hadas get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR, 43134613eb1SYishai Hadas rq->tirn) == obj_id || 43234613eb1SYishai Hadas get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS, 43334613eb1SYishai Hadas sq->tisn) == obj_id); 43434613eb1SYishai Hadas } 43534613eb1SYishai Hadas 43634613eb1SYishai Hadas if (qp_type == MLX5_IB_QPT_DCT) 43734613eb1SYishai Hadas return get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT, 43834613eb1SYishai Hadas qp->dct.mdct.mqp.qpn) == obj_id; 43934613eb1SYishai Hadas 44034613eb1SYishai Hadas return get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 44134613eb1SYishai Hadas qp->ibqp.qp_num) == obj_id; 44234613eb1SYishai Hadas } 44334613eb1SYishai Hadas 44434613eb1SYishai Hadas case UVERBS_OBJECT_WQ: 44534613eb1SYishai Hadas return get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 44634613eb1SYishai Hadas to_mrwq(uobj->object)->core_qp.qpn) == 44734613eb1SYishai Hadas obj_id; 44834613eb1SYishai Hadas 44934613eb1SYishai Hadas case UVERBS_OBJECT_RWQ_IND_TBL: 45034613eb1SYishai Hadas return get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT, 45134613eb1SYishai Hadas to_mrwq_ind_table(uobj->object)->rqtn) == 45234613eb1SYishai Hadas obj_id; 45334613eb1SYishai Hadas 45434613eb1SYishai Hadas case MLX5_IB_OBJECT_DEVX_OBJ: 45534613eb1SYishai Hadas return ((struct devx_obj *)uobj->object)->obj_id == obj_id; 45634613eb1SYishai Hadas 457e662e14dSYishai Hadas default: 458e662e14dSYishai Hadas return false; 459e662e14dSYishai Hadas } 460e662e14dSYishai Hadas } 461e662e14dSYishai Hadas 462ba1a057dSYishai Hadas static void devx_set_umem_valid(const void *in) 463ba1a057dSYishai Hadas { 464ba1a057dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 465ba1a057dSYishai Hadas 466ba1a057dSYishai Hadas switch (opcode) { 467ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_MKEY: 468ba1a057dSYishai Hadas MLX5_SET(create_mkey_in, in, mkey_umem_valid, 1); 469ba1a057dSYishai Hadas break; 470ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_CQ: 471ba1a057dSYishai Hadas { 472ba1a057dSYishai Hadas void *cqc; 473ba1a057dSYishai Hadas 474ba1a057dSYishai Hadas MLX5_SET(create_cq_in, in, cq_umem_valid, 1); 475ba1a057dSYishai Hadas cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context); 476ba1a057dSYishai Hadas MLX5_SET(cqc, cqc, dbr_umem_valid, 1); 477ba1a057dSYishai Hadas break; 478ba1a057dSYishai Hadas } 479ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_QP: 480ba1a057dSYishai Hadas { 481ba1a057dSYishai Hadas void *qpc; 482ba1a057dSYishai Hadas 483ba1a057dSYishai Hadas qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); 484ba1a057dSYishai Hadas MLX5_SET(qpc, qpc, dbr_umem_valid, 1); 485ba1a057dSYishai Hadas MLX5_SET(create_qp_in, in, wq_umem_valid, 1); 486ba1a057dSYishai Hadas break; 487ba1a057dSYishai Hadas } 488ba1a057dSYishai Hadas 489ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_RQ: 490ba1a057dSYishai Hadas { 491ba1a057dSYishai Hadas void *rqc, *wq; 492ba1a057dSYishai Hadas 493ba1a057dSYishai Hadas rqc = MLX5_ADDR_OF(create_rq_in, in, ctx); 494ba1a057dSYishai Hadas wq = MLX5_ADDR_OF(rqc, rqc, wq); 495ba1a057dSYishai Hadas MLX5_SET(wq, wq, dbr_umem_valid, 1); 496ba1a057dSYishai Hadas MLX5_SET(wq, wq, wq_umem_valid, 1); 497ba1a057dSYishai Hadas break; 498ba1a057dSYishai Hadas } 499ba1a057dSYishai Hadas 500ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_SQ: 501ba1a057dSYishai Hadas { 502ba1a057dSYishai Hadas void *sqc, *wq; 503ba1a057dSYishai Hadas 504ba1a057dSYishai Hadas sqc = MLX5_ADDR_OF(create_sq_in, in, ctx); 505ba1a057dSYishai Hadas wq = MLX5_ADDR_OF(sqc, sqc, wq); 506ba1a057dSYishai Hadas MLX5_SET(wq, wq, dbr_umem_valid, 1); 507ba1a057dSYishai Hadas MLX5_SET(wq, wq, wq_umem_valid, 1); 508ba1a057dSYishai Hadas break; 509ba1a057dSYishai Hadas } 510ba1a057dSYishai Hadas 511ba1a057dSYishai Hadas case MLX5_CMD_OP_MODIFY_CQ: 512ba1a057dSYishai Hadas MLX5_SET(modify_cq_in, in, cq_umem_valid, 1); 513ba1a057dSYishai Hadas break; 514ba1a057dSYishai Hadas 515ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_RMP: 516ba1a057dSYishai Hadas { 517ba1a057dSYishai Hadas void *rmpc, *wq; 518ba1a057dSYishai Hadas 519ba1a057dSYishai Hadas rmpc = MLX5_ADDR_OF(create_rmp_in, in, ctx); 520ba1a057dSYishai Hadas wq = MLX5_ADDR_OF(rmpc, rmpc, wq); 521ba1a057dSYishai Hadas MLX5_SET(wq, wq, dbr_umem_valid, 1); 522ba1a057dSYishai Hadas MLX5_SET(wq, wq, wq_umem_valid, 1); 523ba1a057dSYishai Hadas break; 524ba1a057dSYishai Hadas } 525ba1a057dSYishai Hadas 526ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_XRQ: 527ba1a057dSYishai Hadas { 528ba1a057dSYishai Hadas void *xrqc, *wq; 529ba1a057dSYishai Hadas 530ba1a057dSYishai Hadas xrqc = MLX5_ADDR_OF(create_xrq_in, in, xrq_context); 531ba1a057dSYishai Hadas wq = MLX5_ADDR_OF(xrqc, xrqc, wq); 532ba1a057dSYishai Hadas MLX5_SET(wq, wq, dbr_umem_valid, 1); 533ba1a057dSYishai Hadas MLX5_SET(wq, wq, wq_umem_valid, 1); 534ba1a057dSYishai Hadas break; 535ba1a057dSYishai Hadas } 536ba1a057dSYishai Hadas 537ba1a057dSYishai Hadas case MLX5_CMD_OP_CREATE_XRC_SRQ: 538ba1a057dSYishai Hadas { 539ba1a057dSYishai Hadas void *xrc_srqc; 540ba1a057dSYishai Hadas 541ba1a057dSYishai Hadas MLX5_SET(create_xrc_srq_in, in, xrc_srq_umem_valid, 1); 542ba1a057dSYishai Hadas xrc_srqc = MLX5_ADDR_OF(create_xrc_srq_in, in, 543ba1a057dSYishai Hadas xrc_srq_context_entry); 544ba1a057dSYishai Hadas MLX5_SET(xrc_srqc, xrc_srqc, dbr_umem_valid, 1); 545ba1a057dSYishai Hadas break; 546ba1a057dSYishai Hadas } 547ba1a057dSYishai Hadas 548ba1a057dSYishai Hadas default: 549ba1a057dSYishai Hadas return; 550ba1a057dSYishai Hadas } 551ba1a057dSYishai Hadas } 552ba1a057dSYishai Hadas 5532351776eSYishai Hadas static bool devx_is_obj_create_cmd(const void *in, u16 *opcode) 5547efce369SYishai Hadas { 5552351776eSYishai Hadas *opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 5567efce369SYishai Hadas 5572351776eSYishai Hadas switch (*opcode) { 5587efce369SYishai Hadas case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 5597efce369SYishai Hadas case MLX5_CMD_OP_CREATE_MKEY: 5607efce369SYishai Hadas case MLX5_CMD_OP_CREATE_CQ: 5617efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_PD: 5627efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 5637efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RMP: 5647efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SQ: 5657efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQ: 5667efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQT: 5677efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIR: 5687efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIS: 5697efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_Q_COUNTER: 5707efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_TABLE: 5717efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_GROUP: 5727efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 57360786f09SMark Bloch case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT: 5747efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 5757efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 5767efce369SYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 5777efce369SYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 5787efce369SYishai Hadas case MLX5_CMD_OP_CREATE_QP: 5797efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SRQ: 5807efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRC_SRQ: 5817efce369SYishai Hadas case MLX5_CMD_OP_CREATE_DCT: 5827efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRQ: 5837efce369SYishai Hadas case MLX5_CMD_OP_ATTACH_TO_MCG: 5847efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_XRCD: 5857efce369SYishai Hadas return true; 5867efce369SYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 5877efce369SYishai Hadas { 5887efce369SYishai Hadas u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 5897efce369SYishai Hadas if (op_mod == 0) 5907efce369SYishai Hadas return true; 5917efce369SYishai Hadas return false; 5927efce369SYishai Hadas } 5937efce369SYishai Hadas default: 5947efce369SYishai Hadas return false; 5957efce369SYishai Hadas } 5967efce369SYishai Hadas } 5977efce369SYishai Hadas 598e662e14dSYishai Hadas static bool devx_is_obj_modify_cmd(const void *in) 599e662e14dSYishai Hadas { 600e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 601e662e14dSYishai Hadas 602e662e14dSYishai Hadas switch (opcode) { 603e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 604e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_CQ: 605e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RMP: 606e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SQ: 607e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQ: 608e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_RQT: 609e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIR: 610e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_TIS: 611e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 612e662e14dSYishai Hadas case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 613e662e14dSYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 614e662e14dSYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 615e662e14dSYishai Hadas case MLX5_CMD_OP_RST2INIT_QP: 616e662e14dSYishai Hadas case MLX5_CMD_OP_INIT2RTR_QP: 617e662e14dSYishai Hadas case MLX5_CMD_OP_RTR2RTS_QP: 618e662e14dSYishai Hadas case MLX5_CMD_OP_RTS2RTS_QP: 619e662e14dSYishai Hadas case MLX5_CMD_OP_SQERR2RTS_QP: 620e662e14dSYishai Hadas case MLX5_CMD_OP_2ERR_QP: 621e662e14dSYishai Hadas case MLX5_CMD_OP_2RST_QP: 622e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRC_SRQ: 623e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_RQ: 624e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 625e662e14dSYishai Hadas case MLX5_CMD_OP_ARM_XRQ: 626719598c9SYishai Hadas case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY: 627e662e14dSYishai Hadas return true; 628e662e14dSYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 629e662e14dSYishai Hadas { 630e662e14dSYishai Hadas u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 631e662e14dSYishai Hadas 632e662e14dSYishai Hadas if (op_mod == 1) 633e662e14dSYishai Hadas return true; 634e662e14dSYishai Hadas return false; 635e662e14dSYishai Hadas } 636e662e14dSYishai Hadas default: 637e662e14dSYishai Hadas return false; 638e662e14dSYishai Hadas } 639e662e14dSYishai Hadas } 640e662e14dSYishai Hadas 641e662e14dSYishai Hadas static bool devx_is_obj_query_cmd(const void *in) 642e662e14dSYishai Hadas { 643e662e14dSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 644e662e14dSYishai Hadas 645e662e14dSYishai Hadas switch (opcode) { 646e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 647e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MKEY: 648e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_CQ: 649e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RMP: 650e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SQ: 651e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQ: 652e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_RQT: 653e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIR: 654e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_TIS: 655e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_Q_COUNTER: 656e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE: 657e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_GROUP: 658e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 659e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 660e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 661e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 662e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 663e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_QP: 664e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_SRQ: 665e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRC_SRQ: 666e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_DCT: 667e662e14dSYishai Hadas case MLX5_CMD_OP_QUERY_XRQ: 668719598c9SYishai Hadas case MLX5_CMD_OP_QUERY_XRQ_DC_PARAMS_ENTRY: 669719598c9SYishai Hadas case MLX5_CMD_OP_QUERY_XRQ_ERROR_PARAMS: 670719598c9SYishai Hadas case MLX5_CMD_OP_QUERY_PACKET_REFORMAT_CONTEXT: 671e662e14dSYishai Hadas return true; 672e662e14dSYishai Hadas default: 673e662e14dSYishai Hadas return false; 674e662e14dSYishai Hadas } 675e662e14dSYishai Hadas } 676e662e14dSYishai Hadas 6777e1335a7SYishai Hadas static bool devx_is_whitelist_cmd(void *in) 6787e1335a7SYishai Hadas { 6797e1335a7SYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 6807e1335a7SYishai Hadas 6817e1335a7SYishai Hadas switch (opcode) { 6827e1335a7SYishai Hadas case MLX5_CMD_OP_QUERY_HCA_CAP: 6837e1335a7SYishai Hadas case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT: 6847e1335a7SYishai Hadas return true; 6857e1335a7SYishai Hadas default: 6867e1335a7SYishai Hadas return false; 6877e1335a7SYishai Hadas } 6887e1335a7SYishai Hadas } 6897e1335a7SYishai Hadas 6907e1335a7SYishai Hadas static int devx_get_uid(struct mlx5_ib_ucontext *c, void *cmd_in) 6917e1335a7SYishai Hadas { 6927e1335a7SYishai Hadas if (devx_is_whitelist_cmd(cmd_in)) { 6937e1335a7SYishai Hadas struct mlx5_ib_dev *dev; 6947e1335a7SYishai Hadas 6957e1335a7SYishai Hadas if (c->devx_uid) 6967e1335a7SYishai Hadas return c->devx_uid; 6977e1335a7SYishai Hadas 6987e1335a7SYishai Hadas dev = to_mdev(c->ibucontext.device); 6997e1335a7SYishai Hadas if (dev->devx_whitelist_uid) 7007e1335a7SYishai Hadas return dev->devx_whitelist_uid; 7017e1335a7SYishai Hadas 7027e1335a7SYishai Hadas return -EOPNOTSUPP; 7037e1335a7SYishai Hadas } 7047e1335a7SYishai Hadas 7057e1335a7SYishai Hadas if (!c->devx_uid) 7067e1335a7SYishai Hadas return -EINVAL; 7077e1335a7SYishai Hadas 7087e1335a7SYishai Hadas return c->devx_uid; 7097e1335a7SYishai Hadas } 710e662e14dSYishai Hadas static bool devx_is_general_cmd(void *in) 7118aa8c95cSYishai Hadas { 7128aa8c95cSYishai Hadas u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 7138aa8c95cSYishai Hadas 714719598c9SYishai Hadas if (opcode >= MLX5_CMD_OP_GENERAL_START && 715719598c9SYishai Hadas opcode < MLX5_CMD_OP_GENERAL_END) 716719598c9SYishai Hadas return true; 717719598c9SYishai Hadas 7188aa8c95cSYishai Hadas switch (opcode) { 7198aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_HCA_CAP: 7207e1335a7SYishai Hadas case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT: 7218aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VPORT_STATE: 7228aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ADAPTER: 7238aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ISSI: 7248aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT: 7258aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_ROCE_ADDRESS: 7268aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VNIC_ENV: 7278aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_VPORT_COUNTER: 7288aa8c95cSYishai Hadas case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG: 7298aa8c95cSYishai Hadas case MLX5_CMD_OP_NOP: 7308aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_STATUS: 7318aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_PARAMS: 7328aa8c95cSYishai Hadas case MLX5_CMD_OP_QUERY_CONG_STATISTICS: 7338aa8c95cSYishai Hadas return true; 7348aa8c95cSYishai Hadas default: 7358aa8c95cSYishai Hadas return false; 7368aa8c95cSYishai Hadas } 7378aa8c95cSYishai Hadas } 7388aa8c95cSYishai Hadas 739e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_EQN)( 74015a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 741f6fe01b7SYishai Hadas { 742e83f0ecdSJason Gunthorpe struct mlx5_ib_ucontext *c; 743e83f0ecdSJason Gunthorpe struct mlx5_ib_dev *dev; 744f6fe01b7SYishai Hadas int user_vector; 745f6fe01b7SYishai Hadas int dev_eqn; 746f6fe01b7SYishai Hadas unsigned int irqn; 747f6fe01b7SYishai Hadas int err; 748f6fe01b7SYishai Hadas 749f6fe01b7SYishai Hadas if (uverbs_copy_from(&user_vector, attrs, 750f6fe01b7SYishai Hadas MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC)) 751f6fe01b7SYishai Hadas return -EFAULT; 752f6fe01b7SYishai Hadas 75315a1b4beSJason Gunthorpe c = devx_ufile2uctx(attrs); 754e83f0ecdSJason Gunthorpe if (IS_ERR(c)) 755e83f0ecdSJason Gunthorpe return PTR_ERR(c); 756e83f0ecdSJason Gunthorpe dev = to_mdev(c->ibucontext.device); 757e83f0ecdSJason Gunthorpe 758f6fe01b7SYishai Hadas err = mlx5_vector2eqn(dev->mdev, user_vector, &dev_eqn, &irqn); 759f6fe01b7SYishai Hadas if (err < 0) 760f6fe01b7SYishai Hadas return err; 761f6fe01b7SYishai Hadas 762f6fe01b7SYishai Hadas if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN, 763f6fe01b7SYishai Hadas &dev_eqn, sizeof(dev_eqn))) 764f6fe01b7SYishai Hadas return -EFAULT; 765f6fe01b7SYishai Hadas 766f6fe01b7SYishai Hadas return 0; 767f6fe01b7SYishai Hadas } 768f6fe01b7SYishai Hadas 7697c043e90SYishai Hadas /* 7707c043e90SYishai Hadas *Security note: 7717c043e90SYishai Hadas * The hardware protection mechanism works like this: Each device object that 7727c043e90SYishai Hadas * is subject to UAR doorbells (QP/SQ/CQ) gets a UAR ID (called uar_page in 7737c043e90SYishai Hadas * the device specification manual) upon its creation. Then upon doorbell, 7747c043e90SYishai Hadas * hardware fetches the object context for which the doorbell was rang, and 7757c043e90SYishai Hadas * validates that the UAR through which the DB was rang matches the UAR ID 7767c043e90SYishai Hadas * of the object. 7777c043e90SYishai Hadas * If no match the doorbell is silently ignored by the hardware. Of course, 7787c043e90SYishai Hadas * the user cannot ring a doorbell on a UAR that was not mapped to it. 7797c043e90SYishai Hadas * Now in devx, as the devx kernel does not manipulate the QP/SQ/CQ command 7807c043e90SYishai Hadas * mailboxes (except tagging them with UID), we expose to the user its UAR 7817c043e90SYishai Hadas * ID, so it can embed it in these objects in the expected specification 7827c043e90SYishai Hadas * format. So the only thing the user can do is hurt itself by creating a 7837c043e90SYishai Hadas * QP/SQ/CQ with a UAR ID other than his, and then in this case other users 7847c043e90SYishai Hadas * may ring a doorbell on its objects. 7857c043e90SYishai Hadas * The consequence of that will be that another user can schedule a QP/SQ 7867c043e90SYishai Hadas * of the buggy user for execution (just insert it to the hardware schedule 7877c043e90SYishai Hadas * queue or arm its CQ for event generation), no further harm is expected. 7887c043e90SYishai Hadas */ 789e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_UAR)( 79015a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 7917c043e90SYishai Hadas { 79222fa27fbSJason Gunthorpe struct mlx5_ib_ucontext *c; 79322fa27fbSJason Gunthorpe struct mlx5_ib_dev *dev; 7947c043e90SYishai Hadas u32 user_idx; 7957c043e90SYishai Hadas s32 dev_idx; 7967c043e90SYishai Hadas 79715a1b4beSJason Gunthorpe c = devx_ufile2uctx(attrs); 79822fa27fbSJason Gunthorpe if (IS_ERR(c)) 79922fa27fbSJason Gunthorpe return PTR_ERR(c); 80022fa27fbSJason Gunthorpe dev = to_mdev(c->ibucontext.device); 80122fa27fbSJason Gunthorpe 8027c043e90SYishai Hadas if (uverbs_copy_from(&user_idx, attrs, 8037c043e90SYishai Hadas MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX)) 8047c043e90SYishai Hadas return -EFAULT; 8057c043e90SYishai Hadas 80622fa27fbSJason Gunthorpe dev_idx = bfregn_to_uar_index(dev, &c->bfregi, user_idx, true); 8077c043e90SYishai Hadas if (dev_idx < 0) 8087c043e90SYishai Hadas return dev_idx; 8097c043e90SYishai Hadas 8107c043e90SYishai Hadas if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, 8117c043e90SYishai Hadas &dev_idx, sizeof(dev_idx))) 8127c043e90SYishai Hadas return -EFAULT; 8137c043e90SYishai Hadas 8147c043e90SYishai Hadas return 0; 8157c043e90SYishai Hadas } 8167c043e90SYishai Hadas 817e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)( 81815a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 8198aa8c95cSYishai Hadas { 82022fa27fbSJason Gunthorpe struct mlx5_ib_ucontext *c; 82122fa27fbSJason Gunthorpe struct mlx5_ib_dev *dev; 8227efce369SYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr( 8237efce369SYishai Hadas attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN); 8248aa8c95cSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 8258aa8c95cSYishai Hadas MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT); 8268aa8c95cSYishai Hadas void *cmd_out; 8278aa8c95cSYishai Hadas int err; 8287e1335a7SYishai Hadas int uid; 8298aa8c95cSYishai Hadas 83015a1b4beSJason Gunthorpe c = devx_ufile2uctx(attrs); 83122fa27fbSJason Gunthorpe if (IS_ERR(c)) 83222fa27fbSJason Gunthorpe return PTR_ERR(c); 83322fa27fbSJason Gunthorpe dev = to_mdev(c->ibucontext.device); 83422fa27fbSJason Gunthorpe 8357e1335a7SYishai Hadas uid = devx_get_uid(c, cmd_in); 8367e1335a7SYishai Hadas if (uid < 0) 8377e1335a7SYishai Hadas return uid; 8388aa8c95cSYishai Hadas 8398aa8c95cSYishai Hadas /* Only white list of some general HCA commands are allowed for this method. */ 8408aa8c95cSYishai Hadas if (!devx_is_general_cmd(cmd_in)) 8418aa8c95cSYishai Hadas return -EINVAL; 8428aa8c95cSYishai Hadas 843b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 844b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 845b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 8468aa8c95cSYishai Hadas 8477e1335a7SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 8488aa8c95cSYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 8498aa8c95cSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN), 8508aa8c95cSYishai Hadas cmd_out, cmd_out_len); 8518aa8c95cSYishai Hadas if (err) 8528aa8c95cSYishai Hadas return err; 853b61815e2SJason Gunthorpe 854b61815e2SJason Gunthorpe return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out, 855b61815e2SJason Gunthorpe cmd_out_len); 8568aa8c95cSYishai Hadas } 8578aa8c95cSYishai Hadas 8587efce369SYishai Hadas static void devx_obj_build_destroy_cmd(void *in, void *out, void *din, 8597efce369SYishai Hadas u32 *dinlen, 8607efce369SYishai Hadas u32 *obj_id) 8617efce369SYishai Hadas { 8627efce369SYishai Hadas u16 obj_type = MLX5_GET(general_obj_in_cmd_hdr, in, obj_type); 8637efce369SYishai Hadas u16 uid = MLX5_GET(general_obj_in_cmd_hdr, in, uid); 8647efce369SYishai Hadas 8657efce369SYishai Hadas *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 8667efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr); 8677efce369SYishai Hadas 8687efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, obj_id, *obj_id); 8697efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, uid, uid); 8707efce369SYishai Hadas 8717efce369SYishai Hadas switch (MLX5_GET(general_obj_in_cmd_hdr, in, opcode)) { 8727efce369SYishai Hadas case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 8737efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 8747efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, obj_type, obj_type); 8757efce369SYishai Hadas break; 8767efce369SYishai Hadas 8776e3722baSYishai Hadas case MLX5_CMD_OP_CREATE_UMEM: 8786e3722baSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 8796e3722baSYishai Hadas MLX5_CMD_OP_DESTROY_UMEM); 8806e3722baSYishai Hadas break; 8817efce369SYishai Hadas case MLX5_CMD_OP_CREATE_MKEY: 8827efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_MKEY); 8837efce369SYishai Hadas break; 8847efce369SYishai Hadas case MLX5_CMD_OP_CREATE_CQ: 8857efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_CQ); 8867efce369SYishai Hadas break; 8877efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_PD: 8887efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_PD); 8897efce369SYishai Hadas break; 8907efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 8917efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 8927efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN); 8937efce369SYishai Hadas break; 8947efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RMP: 8957efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RMP); 8967efce369SYishai Hadas break; 8977efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SQ: 8987efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SQ); 8997efce369SYishai Hadas break; 9007efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQ: 9017efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQ); 9027efce369SYishai Hadas break; 9037efce369SYishai Hadas case MLX5_CMD_OP_CREATE_RQT: 9047efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT); 9057efce369SYishai Hadas break; 9067efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIR: 9077efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIR); 9087efce369SYishai Hadas break; 9097efce369SYishai Hadas case MLX5_CMD_OP_CREATE_TIS: 9107efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS); 9117efce369SYishai Hadas break; 9127efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_Q_COUNTER: 9137efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9147efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_Q_COUNTER); 9157efce369SYishai Hadas break; 9167efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_TABLE: 9177efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_table_in); 9187efce369SYishai Hadas *obj_id = MLX5_GET(create_flow_table_out, out, table_id); 9197efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, other_vport, 9207efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, other_vport)); 9217efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, vport_number, 9227efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, vport_number)); 9237efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, table_type, 9247efce369SYishai Hadas MLX5_GET(create_flow_table_in, in, table_type)); 9257efce369SYishai Hadas MLX5_SET(destroy_flow_table_in, din, table_id, *obj_id); 9267efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9277efce369SYishai Hadas MLX5_CMD_OP_DESTROY_FLOW_TABLE); 9287efce369SYishai Hadas break; 9297efce369SYishai Hadas case MLX5_CMD_OP_CREATE_FLOW_GROUP: 9307efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_group_in); 9317efce369SYishai Hadas *obj_id = MLX5_GET(create_flow_group_out, out, group_id); 9327efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, other_vport, 9337efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, other_vport)); 9347efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, vport_number, 9357efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, vport_number)); 9367efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, table_type, 9377efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, table_type)); 9387efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, table_id, 9397efce369SYishai Hadas MLX5_GET(create_flow_group_in, in, table_id)); 9407efce369SYishai Hadas MLX5_SET(destroy_flow_group_in, din, group_id, *obj_id); 9417efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9427efce369SYishai Hadas MLX5_CMD_OP_DESTROY_FLOW_GROUP); 9437efce369SYishai Hadas break; 9447efce369SYishai Hadas case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 9457efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_fte_in); 9467efce369SYishai Hadas *obj_id = MLX5_GET(set_fte_in, in, flow_index); 9477efce369SYishai Hadas MLX5_SET(delete_fte_in, din, other_vport, 9487efce369SYishai Hadas MLX5_GET(set_fte_in, in, other_vport)); 9497efce369SYishai Hadas MLX5_SET(delete_fte_in, din, vport_number, 9507efce369SYishai Hadas MLX5_GET(set_fte_in, in, vport_number)); 9517efce369SYishai Hadas MLX5_SET(delete_fte_in, din, table_type, 9527efce369SYishai Hadas MLX5_GET(set_fte_in, in, table_type)); 9537efce369SYishai Hadas MLX5_SET(delete_fte_in, din, table_id, 9547efce369SYishai Hadas MLX5_GET(set_fte_in, in, table_id)); 9557efce369SYishai Hadas MLX5_SET(delete_fte_in, din, flow_index, *obj_id); 9567efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9577efce369SYishai Hadas MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); 9587efce369SYishai Hadas break; 9597efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 9607efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9617efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_FLOW_COUNTER); 9627efce369SYishai Hadas break; 96360786f09SMark Bloch case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT: 9647efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 96560786f09SMark Bloch MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT); 9667efce369SYishai Hadas break; 9677efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 9687efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9697efce369SYishai Hadas MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT); 9707efce369SYishai Hadas break; 9717efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 9727efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(destroy_scheduling_element_in); 9737efce369SYishai Hadas *obj_id = MLX5_GET(create_scheduling_element_out, out, 9747efce369SYishai Hadas scheduling_element_id); 9757efce369SYishai Hadas MLX5_SET(destroy_scheduling_element_in, din, 9767efce369SYishai Hadas scheduling_hierarchy, 9777efce369SYishai Hadas MLX5_GET(create_scheduling_element_in, in, 9787efce369SYishai Hadas scheduling_hierarchy)); 9797efce369SYishai Hadas MLX5_SET(destroy_scheduling_element_in, din, 9807efce369SYishai Hadas scheduling_element_id, *obj_id); 9817efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9827efce369SYishai Hadas MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT); 9837efce369SYishai Hadas break; 9847efce369SYishai Hadas case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 9857efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_vxlan_udp_dport_in); 9867efce369SYishai Hadas *obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port); 9877efce369SYishai Hadas MLX5_SET(delete_vxlan_udp_dport_in, din, vxlan_udp_port, *obj_id); 9887efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9897efce369SYishai Hadas MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT); 9907efce369SYishai Hadas break; 9917efce369SYishai Hadas case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 9927efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(delete_l2_table_entry_in); 9937efce369SYishai Hadas *obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index); 9947efce369SYishai Hadas MLX5_SET(delete_l2_table_entry_in, din, table_index, *obj_id); 9957efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 9967efce369SYishai Hadas MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY); 9977efce369SYishai Hadas break; 9987efce369SYishai Hadas case MLX5_CMD_OP_CREATE_QP: 9997efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_QP); 10007efce369SYishai Hadas break; 10017efce369SYishai Hadas case MLX5_CMD_OP_CREATE_SRQ: 10027efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SRQ); 10037efce369SYishai Hadas break; 10047efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRC_SRQ: 10057efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 10067efce369SYishai Hadas MLX5_CMD_OP_DESTROY_XRC_SRQ); 10077efce369SYishai Hadas break; 10087efce369SYishai Hadas case MLX5_CMD_OP_CREATE_DCT: 10097efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_DCT); 10107efce369SYishai Hadas break; 10117efce369SYishai Hadas case MLX5_CMD_OP_CREATE_XRQ: 10127efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_XRQ); 10137efce369SYishai Hadas break; 10147efce369SYishai Hadas case MLX5_CMD_OP_ATTACH_TO_MCG: 10157efce369SYishai Hadas *dinlen = MLX5_ST_SZ_BYTES(detach_from_mcg_in); 10167efce369SYishai Hadas MLX5_SET(detach_from_mcg_in, din, qpn, 10177efce369SYishai Hadas MLX5_GET(attach_to_mcg_in, in, qpn)); 10187efce369SYishai Hadas memcpy(MLX5_ADDR_OF(detach_from_mcg_in, din, multicast_gid), 10197efce369SYishai Hadas MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid), 10207efce369SYishai Hadas MLX5_FLD_SZ_BYTES(attach_to_mcg_in, multicast_gid)); 10217efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DETACH_FROM_MCG); 10227efce369SYishai Hadas break; 10237efce369SYishai Hadas case MLX5_CMD_OP_ALLOC_XRCD: 10247efce369SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD); 10257efce369SYishai Hadas break; 10267efce369SYishai Hadas default: 10277efce369SYishai Hadas /* The entry must match to one of the devx_is_obj_create_cmd */ 10287efce369SYishai Hadas WARN_ON(true); 10297efce369SYishai Hadas break; 10307efce369SYishai Hadas } 10317efce369SYishai Hadas } 10327efce369SYishai Hadas 1033534fd7aaSYishai Hadas static int devx_handle_mkey_indirect(struct devx_obj *obj, 1034534fd7aaSYishai Hadas struct mlx5_ib_dev *dev, 1035534fd7aaSYishai Hadas void *in, void *out) 1036534fd7aaSYishai Hadas { 1037534fd7aaSYishai Hadas struct mlx5_mkey_table *table = &dev->mdev->priv.mkey_table; 1038534fd7aaSYishai Hadas struct mlx5_ib_devx_mr *devx_mr = &obj->devx_mr; 1039534fd7aaSYishai Hadas unsigned long flags; 1040534fd7aaSYishai Hadas struct mlx5_core_mkey *mkey; 1041534fd7aaSYishai Hadas void *mkc; 1042534fd7aaSYishai Hadas u8 key; 1043534fd7aaSYishai Hadas int err; 1044534fd7aaSYishai Hadas 1045534fd7aaSYishai Hadas mkey = &devx_mr->mmkey; 1046534fd7aaSYishai Hadas mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); 1047534fd7aaSYishai Hadas key = MLX5_GET(mkc, mkc, mkey_7_0); 1048534fd7aaSYishai Hadas mkey->key = mlx5_idx_to_mkey( 1049534fd7aaSYishai Hadas MLX5_GET(create_mkey_out, out, mkey_index)) | key; 1050534fd7aaSYishai Hadas mkey->type = MLX5_MKEY_INDIRECT_DEVX; 1051534fd7aaSYishai Hadas mkey->iova = MLX5_GET64(mkc, mkc, start_addr); 1052534fd7aaSYishai Hadas mkey->size = MLX5_GET64(mkc, mkc, len); 1053534fd7aaSYishai Hadas mkey->pd = MLX5_GET(mkc, mkc, pd); 1054534fd7aaSYishai Hadas devx_mr->ndescs = MLX5_GET(mkc, mkc, translations_octword_size); 1055534fd7aaSYishai Hadas 1056534fd7aaSYishai Hadas write_lock_irqsave(&table->lock, flags); 1057534fd7aaSYishai Hadas err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key), 1058534fd7aaSYishai Hadas mkey); 1059534fd7aaSYishai Hadas write_unlock_irqrestore(&table->lock, flags); 1060534fd7aaSYishai Hadas return err; 1061534fd7aaSYishai Hadas } 1062534fd7aaSYishai Hadas 1063fa31f143SYishai Hadas static int devx_handle_mkey_create(struct mlx5_ib_dev *dev, 1064fa31f143SYishai Hadas struct devx_obj *obj, 1065fa31f143SYishai Hadas void *in, int in_len) 1066fa31f143SYishai Hadas { 1067fa31f143SYishai Hadas int min_len = MLX5_BYTE_OFF(create_mkey_in, memory_key_mkey_entry) + 1068fa31f143SYishai Hadas MLX5_FLD_SZ_BYTES(create_mkey_in, 1069fa31f143SYishai Hadas memory_key_mkey_entry); 1070fa31f143SYishai Hadas void *mkc; 1071fa31f143SYishai Hadas u8 access_mode; 1072fa31f143SYishai Hadas 1073fa31f143SYishai Hadas if (in_len < min_len) 1074fa31f143SYishai Hadas return -EINVAL; 1075fa31f143SYishai Hadas 1076fa31f143SYishai Hadas mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); 1077fa31f143SYishai Hadas 1078fa31f143SYishai Hadas access_mode = MLX5_GET(mkc, mkc, access_mode_1_0); 1079fa31f143SYishai Hadas access_mode |= MLX5_GET(mkc, mkc, access_mode_4_2) << 2; 1080fa31f143SYishai Hadas 1081fa31f143SYishai Hadas if (access_mode == MLX5_MKC_ACCESS_MODE_KLMS || 1082534fd7aaSYishai Hadas access_mode == MLX5_MKC_ACCESS_MODE_KSM) { 1083534fd7aaSYishai Hadas if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) 1084534fd7aaSYishai Hadas obj->flags |= DEVX_OBJ_FLAGS_INDIRECT_MKEY; 1085fa31f143SYishai Hadas return 0; 1086534fd7aaSYishai Hadas } 1087fa31f143SYishai Hadas 1088fa31f143SYishai Hadas MLX5_SET(create_mkey_in, in, mkey_umem_valid, 1); 1089fa31f143SYishai Hadas return 0; 1090fa31f143SYishai Hadas } 1091fa31f143SYishai Hadas 1092534fd7aaSYishai Hadas static void devx_free_indirect_mkey(struct rcu_head *rcu) 1093534fd7aaSYishai Hadas { 1094534fd7aaSYishai Hadas kfree(container_of(rcu, struct devx_obj, devx_mr.rcu)); 1095534fd7aaSYishai Hadas } 1096534fd7aaSYishai Hadas 1097534fd7aaSYishai Hadas /* This function to delete from the radix tree needs to be called before 1098534fd7aaSYishai Hadas * destroying the underlying mkey. Otherwise a race might occur in case that 1099534fd7aaSYishai Hadas * other thread will get the same mkey before this one will be deleted, 1100534fd7aaSYishai Hadas * in that case it will fail via inserting to the tree its own data. 1101534fd7aaSYishai Hadas * 1102534fd7aaSYishai Hadas * Note: 1103534fd7aaSYishai Hadas * An error in the destroy is not expected unless there is some other indirect 1104534fd7aaSYishai Hadas * mkey which points to this one. In a kernel cleanup flow it will be just 1105534fd7aaSYishai Hadas * destroyed in the iterative destruction call. In a user flow, in case 1106534fd7aaSYishai Hadas * the application didn't close in the expected order it's its own problem, 1107534fd7aaSYishai Hadas * the mkey won't be part of the tree, in both cases the kernel is safe. 1108534fd7aaSYishai Hadas */ 1109534fd7aaSYishai Hadas static void devx_cleanup_mkey(struct devx_obj *obj) 1110534fd7aaSYishai Hadas { 1111534fd7aaSYishai Hadas struct mlx5_mkey_table *table = &obj->mdev->priv.mkey_table; 1112534fd7aaSYishai Hadas unsigned long flags; 1113534fd7aaSYishai Hadas 1114534fd7aaSYishai Hadas write_lock_irqsave(&table->lock, flags); 1115e5c1bb47SKamal Heib radix_tree_delete(&table->tree, mlx5_base_mkey(obj->devx_mr.mmkey.key)); 1116534fd7aaSYishai Hadas write_unlock_irqrestore(&table->lock, flags); 1117534fd7aaSYishai Hadas } 1118534fd7aaSYishai Hadas 11197efce369SYishai Hadas static int devx_obj_cleanup(struct ib_uobject *uobject, 11207efce369SYishai Hadas enum rdma_remove_reason why) 11217efce369SYishai Hadas { 11227efce369SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 11237efce369SYishai Hadas struct devx_obj *obj = uobject->object; 11247efce369SYishai Hadas int ret; 11257efce369SYishai Hadas 1126534fd7aaSYishai Hadas if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) 1127534fd7aaSYishai Hadas devx_cleanup_mkey(obj); 1128534fd7aaSYishai Hadas 1129*c5ae1954SYishai Hadas if (obj->flags & DEVX_OBJ_FLAGS_DCT) 1130*c5ae1954SYishai Hadas ret = mlx5_core_destroy_dct(obj->mdev, &obj->core_dct); 1131*c5ae1954SYishai Hadas else 1132*c5ae1954SYishai Hadas ret = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, 1133*c5ae1954SYishai Hadas sizeof(out)); 11341c77483eSYishai Hadas if (ib_is_destroy_retryable(ret, why, uobject)) 11357efce369SYishai Hadas return ret; 11367efce369SYishai Hadas 1137534fd7aaSYishai Hadas if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { 1138534fd7aaSYishai Hadas struct mlx5_ib_dev *dev = to_mdev(uobject->context->device); 1139534fd7aaSYishai Hadas 1140534fd7aaSYishai Hadas call_srcu(&dev->mr_srcu, &obj->devx_mr.rcu, 1141534fd7aaSYishai Hadas devx_free_indirect_mkey); 1142534fd7aaSYishai Hadas return ret; 1143534fd7aaSYishai Hadas } 1144534fd7aaSYishai Hadas 11457efce369SYishai Hadas kfree(obj); 11467efce369SYishai Hadas return ret; 11477efce369SYishai Hadas } 11487efce369SYishai Hadas 1149e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)( 115015a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 11517efce369SYishai Hadas { 11527efce369SYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN); 11537efce369SYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 11547efce369SYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT); 1155fa31f143SYishai Hadas int cmd_in_len = uverbs_attr_get_len(attrs, 1156fa31f143SYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN); 11577efce369SYishai Hadas void *cmd_out; 1158c36ee46dSJason Gunthorpe struct ib_uobject *uobj = uverbs_attr_get_uobject( 1159c36ee46dSJason Gunthorpe attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE); 116089944450SShamir Rabinovitch struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 116189944450SShamir Rabinovitch &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 1162c36ee46dSJason Gunthorpe struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 1163e8ef090aSYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 11647efce369SYishai Hadas struct devx_obj *obj; 11657efce369SYishai Hadas int err; 11667e1335a7SYishai Hadas int uid; 11672351776eSYishai Hadas u32 obj_id; 11682351776eSYishai Hadas u16 opcode; 11697efce369SYishai Hadas 11707e1335a7SYishai Hadas uid = devx_get_uid(c, cmd_in); 11717e1335a7SYishai Hadas if (uid < 0) 11727e1335a7SYishai Hadas return uid; 11737efce369SYishai Hadas 11742351776eSYishai Hadas if (!devx_is_obj_create_cmd(cmd_in, &opcode)) 11757efce369SYishai Hadas return -EINVAL; 11767efce369SYishai Hadas 1177b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 1178b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 1179b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 1180b61815e2SJason Gunthorpe 11817efce369SYishai Hadas obj = kzalloc(sizeof(struct devx_obj), GFP_KERNEL); 11827efce369SYishai Hadas if (!obj) 11837efce369SYishai Hadas return -ENOMEM; 11847efce369SYishai Hadas 11857e1335a7SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 1186fa31f143SYishai Hadas if (opcode == MLX5_CMD_OP_CREATE_MKEY) { 1187fa31f143SYishai Hadas err = devx_handle_mkey_create(dev, obj, cmd_in, cmd_in_len); 1188fa31f143SYishai Hadas if (err) 1189fa31f143SYishai Hadas goto obj_free; 1190fa31f143SYishai Hadas } else { 1191ba1a057dSYishai Hadas devx_set_umem_valid(cmd_in); 1192fa31f143SYishai Hadas } 1193ba1a057dSYishai Hadas 1194*c5ae1954SYishai Hadas if (opcode == MLX5_CMD_OP_CREATE_DCT) { 1195*c5ae1954SYishai Hadas obj->flags |= DEVX_OBJ_FLAGS_DCT; 1196*c5ae1954SYishai Hadas err = mlx5_core_create_dct(dev->mdev, &obj->core_dct, 1197*c5ae1954SYishai Hadas cmd_in, cmd_in_len, 1198*c5ae1954SYishai Hadas cmd_out, cmd_out_len); 1199*c5ae1954SYishai Hadas } else { 12007efce369SYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd_in, 1201fa31f143SYishai Hadas cmd_in_len, 12027efce369SYishai Hadas cmd_out, cmd_out_len); 1203*c5ae1954SYishai Hadas } 1204*c5ae1954SYishai Hadas 12057efce369SYishai Hadas if (err) 1206b61815e2SJason Gunthorpe goto obj_free; 12077efce369SYishai Hadas 12087efce369SYishai Hadas uobj->object = obj; 12097efce369SYishai Hadas obj->mdev = dev->mdev; 12102351776eSYishai Hadas devx_obj_build_destroy_cmd(cmd_in, cmd_out, obj->dinbox, &obj->dinlen, 12112351776eSYishai Hadas &obj_id); 12127efce369SYishai Hadas WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32)); 12137efce369SYishai Hadas 1214534fd7aaSYishai Hadas if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { 1215534fd7aaSYishai Hadas err = devx_handle_mkey_indirect(obj, dev, cmd_in, cmd_out); 1216534fd7aaSYishai Hadas if (err) 1217534fd7aaSYishai Hadas goto obj_destroy; 1218534fd7aaSYishai Hadas } 1219534fd7aaSYishai Hadas 12207efce369SYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len); 12217efce369SYishai Hadas if (err) 12220da4d48dSYishai Hadas goto err_copy; 12237efce369SYishai Hadas 12242351776eSYishai Hadas obj->obj_id = get_enc_obj_id(opcode, obj_id); 12257efce369SYishai Hadas return 0; 12267efce369SYishai Hadas 12270da4d48dSYishai Hadas err_copy: 1228534fd7aaSYishai Hadas if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) 1229534fd7aaSYishai Hadas devx_cleanup_mkey(obj); 12300da4d48dSYishai Hadas obj_destroy: 1231*c5ae1954SYishai Hadas if (obj->flags & DEVX_OBJ_FLAGS_DCT) 1232*c5ae1954SYishai Hadas mlx5_core_destroy_dct(obj->mdev, &obj->core_dct); 1233*c5ae1954SYishai Hadas else 1234*c5ae1954SYishai Hadas mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, 1235*c5ae1954SYishai Hadas sizeof(out)); 12367efce369SYishai Hadas obj_free: 12377efce369SYishai Hadas kfree(obj); 12387efce369SYishai Hadas return err; 12397efce369SYishai Hadas } 12407efce369SYishai Hadas 1241e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MODIFY)( 124215a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 1243e662e14dSYishai Hadas { 1244e662e14dSYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN); 1245e662e14dSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 1246e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT); 1247e662e14dSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 1248e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE); 124989944450SShamir Rabinovitch struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 125089944450SShamir Rabinovitch &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 125189944450SShamir Rabinovitch struct mlx5_ib_dev *mdev = to_mdev(c->ibucontext.device); 1252e662e14dSYishai Hadas void *cmd_out; 1253e662e14dSYishai Hadas int err; 12547e1335a7SYishai Hadas int uid; 1255e662e14dSYishai Hadas 12567e1335a7SYishai Hadas uid = devx_get_uid(c, cmd_in); 12577e1335a7SYishai Hadas if (uid < 0) 12587e1335a7SYishai Hadas return uid; 1259e662e14dSYishai Hadas 1260e662e14dSYishai Hadas if (!devx_is_obj_modify_cmd(cmd_in)) 1261e662e14dSYishai Hadas return -EINVAL; 1262e662e14dSYishai Hadas 126334613eb1SYishai Hadas if (!devx_is_valid_obj_id(uobj, cmd_in)) 1264e662e14dSYishai Hadas return -EINVAL; 1265e662e14dSYishai Hadas 1266b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 1267b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 1268b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 1269e662e14dSYishai Hadas 12707e1335a7SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 1271ba1a057dSYishai Hadas devx_set_umem_valid(cmd_in); 1272ba1a057dSYishai Hadas 127334613eb1SYishai Hadas err = mlx5_cmd_exec(mdev->mdev, cmd_in, 1274e662e14dSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN), 1275e662e14dSYishai Hadas cmd_out, cmd_out_len); 1276e662e14dSYishai Hadas if (err) 1277e662e14dSYishai Hadas return err; 1278b61815e2SJason Gunthorpe 1279b61815e2SJason Gunthorpe return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 1280b61815e2SJason Gunthorpe cmd_out, cmd_out_len); 1281e662e14dSYishai Hadas } 1282e662e14dSYishai Hadas 1283e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)( 128415a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 1285e662e14dSYishai Hadas { 1286e662e14dSYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN); 1287e662e14dSYishai Hadas int cmd_out_len = uverbs_attr_get_len(attrs, 1288e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT); 1289e662e14dSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 1290e662e14dSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE); 129189944450SShamir Rabinovitch struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 129289944450SShamir Rabinovitch &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 1293e662e14dSYishai Hadas void *cmd_out; 1294e662e14dSYishai Hadas int err; 12957e1335a7SYishai Hadas int uid; 129689944450SShamir Rabinovitch struct mlx5_ib_dev *mdev = to_mdev(c->ibucontext.device); 1297e662e14dSYishai Hadas 12987e1335a7SYishai Hadas uid = devx_get_uid(c, cmd_in); 12997e1335a7SYishai Hadas if (uid < 0) 13007e1335a7SYishai Hadas return uid; 1301e662e14dSYishai Hadas 1302e662e14dSYishai Hadas if (!devx_is_obj_query_cmd(cmd_in)) 1303e662e14dSYishai Hadas return -EINVAL; 1304e662e14dSYishai Hadas 130534613eb1SYishai Hadas if (!devx_is_valid_obj_id(uobj, cmd_in)) 1306e662e14dSYishai Hadas return -EINVAL; 1307e662e14dSYishai Hadas 1308b61815e2SJason Gunthorpe cmd_out = uverbs_zalloc(attrs, cmd_out_len); 1309b61815e2SJason Gunthorpe if (IS_ERR(cmd_out)) 1310b61815e2SJason Gunthorpe return PTR_ERR(cmd_out); 1311e662e14dSYishai Hadas 13127e1335a7SYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 131334613eb1SYishai Hadas err = mlx5_cmd_exec(mdev->mdev, cmd_in, 1314e662e14dSYishai Hadas uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN), 1315e662e14dSYishai Hadas cmd_out, cmd_out_len); 1316e662e14dSYishai Hadas if (err) 1317e662e14dSYishai Hadas return err; 1318b61815e2SJason Gunthorpe 1319b61815e2SJason Gunthorpe return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, 1320b61815e2SJason Gunthorpe cmd_out, cmd_out_len); 1321e662e14dSYishai Hadas } 1322e662e14dSYishai Hadas 13236bf8f22aSYishai Hadas struct devx_async_event_queue { 13246bf8f22aSYishai Hadas spinlock_t lock; 13256bf8f22aSYishai Hadas wait_queue_head_t poll_wait; 13266bf8f22aSYishai Hadas struct list_head event_list; 1327a124edbaSYishai Hadas atomic_t bytes_in_use; 1328eaebaf77SYishai Hadas u8 is_destroyed:1; 13296bf8f22aSYishai Hadas }; 13306bf8f22aSYishai Hadas 13316bf8f22aSYishai Hadas struct devx_async_cmd_event_file { 13326bf8f22aSYishai Hadas struct ib_uobject uobj; 13336bf8f22aSYishai Hadas struct devx_async_event_queue ev_queue; 1334a124edbaSYishai Hadas struct mlx5_async_ctx async_ctx; 13356bf8f22aSYishai Hadas }; 13366bf8f22aSYishai Hadas 13376bf8f22aSYishai Hadas static void devx_init_event_queue(struct devx_async_event_queue *ev_queue) 13386bf8f22aSYishai Hadas { 13396bf8f22aSYishai Hadas spin_lock_init(&ev_queue->lock); 13406bf8f22aSYishai Hadas INIT_LIST_HEAD(&ev_queue->event_list); 13416bf8f22aSYishai Hadas init_waitqueue_head(&ev_queue->poll_wait); 1342a124edbaSYishai Hadas atomic_set(&ev_queue->bytes_in_use, 0); 1343eaebaf77SYishai Hadas ev_queue->is_destroyed = 0; 13446bf8f22aSYishai Hadas } 13456bf8f22aSYishai Hadas 13466bf8f22aSYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC)( 13476bf8f22aSYishai Hadas struct uverbs_attr_bundle *attrs) 13486bf8f22aSYishai Hadas { 13496bf8f22aSYishai Hadas struct devx_async_cmd_event_file *ev_file; 13506bf8f22aSYishai Hadas 13516bf8f22aSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject( 13526bf8f22aSYishai Hadas attrs, MLX5_IB_ATTR_DEVX_ASYNC_CMD_FD_ALLOC_HANDLE); 1353a124edbaSYishai Hadas struct mlx5_ib_dev *mdev = to_mdev(uobj->context->device); 13546bf8f22aSYishai Hadas 13556bf8f22aSYishai Hadas ev_file = container_of(uobj, struct devx_async_cmd_event_file, 13566bf8f22aSYishai Hadas uobj); 13576bf8f22aSYishai Hadas devx_init_event_queue(&ev_file->ev_queue); 1358a124edbaSYishai Hadas mlx5_cmd_init_async_ctx(mdev->mdev, &ev_file->async_ctx); 13596bf8f22aSYishai Hadas return 0; 13606bf8f22aSYishai Hadas } 13616bf8f22aSYishai Hadas 1362a124edbaSYishai Hadas static void devx_query_callback(int status, struct mlx5_async_work *context) 1363a124edbaSYishai Hadas { 1364a124edbaSYishai Hadas struct devx_async_data *async_data = 1365a124edbaSYishai Hadas container_of(context, struct devx_async_data, cb_work); 1366a124edbaSYishai Hadas struct ib_uobject *fd_uobj = async_data->fd_uobj; 1367a124edbaSYishai Hadas struct devx_async_cmd_event_file *ev_file; 1368a124edbaSYishai Hadas struct devx_async_event_queue *ev_queue; 1369a124edbaSYishai Hadas unsigned long flags; 1370a124edbaSYishai Hadas 1371a124edbaSYishai Hadas ev_file = container_of(fd_uobj, struct devx_async_cmd_event_file, 1372a124edbaSYishai Hadas uobj); 1373a124edbaSYishai Hadas ev_queue = &ev_file->ev_queue; 1374a124edbaSYishai Hadas 1375a124edbaSYishai Hadas spin_lock_irqsave(&ev_queue->lock, flags); 1376a124edbaSYishai Hadas list_add_tail(&async_data->list, &ev_queue->event_list); 1377a124edbaSYishai Hadas spin_unlock_irqrestore(&ev_queue->lock, flags); 1378a124edbaSYishai Hadas 1379a124edbaSYishai Hadas wake_up_interruptible(&ev_queue->poll_wait); 1380a124edbaSYishai Hadas fput(fd_uobj->object); 1381a124edbaSYishai Hadas } 1382a124edbaSYishai Hadas 1383a124edbaSYishai Hadas #define MAX_ASYNC_BYTES_IN_USE (1024 * 1024) /* 1MB */ 1384a124edbaSYishai Hadas 1385a124edbaSYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY)( 1386a124edbaSYishai Hadas struct uverbs_attr_bundle *attrs) 1387a124edbaSYishai Hadas { 1388a124edbaSYishai Hadas void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, 1389a124edbaSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN); 1390a124edbaSYishai Hadas struct ib_uobject *uobj = uverbs_attr_get_uobject( 1391a124edbaSYishai Hadas attrs, 1392a124edbaSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_HANDLE); 1393a124edbaSYishai Hadas u16 cmd_out_len; 139489944450SShamir Rabinovitch struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 139589944450SShamir Rabinovitch &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 1396a124edbaSYishai Hadas struct ib_uobject *fd_uobj; 1397a124edbaSYishai Hadas int err; 1398a124edbaSYishai Hadas int uid; 139989944450SShamir Rabinovitch struct mlx5_ib_dev *mdev = to_mdev(c->ibucontext.device); 1400a124edbaSYishai Hadas struct devx_async_cmd_event_file *ev_file; 1401a124edbaSYishai Hadas struct devx_async_data *async_data; 1402a124edbaSYishai Hadas 1403a124edbaSYishai Hadas uid = devx_get_uid(c, cmd_in); 1404a124edbaSYishai Hadas if (uid < 0) 1405a124edbaSYishai Hadas return uid; 1406a124edbaSYishai Hadas 1407a124edbaSYishai Hadas if (!devx_is_obj_query_cmd(cmd_in)) 1408a124edbaSYishai Hadas return -EINVAL; 1409a124edbaSYishai Hadas 1410a124edbaSYishai Hadas err = uverbs_get_const(&cmd_out_len, attrs, 1411a124edbaSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_OUT_LEN); 1412a124edbaSYishai Hadas if (err) 1413a124edbaSYishai Hadas return err; 1414a124edbaSYishai Hadas 1415a124edbaSYishai Hadas if (!devx_is_valid_obj_id(uobj, cmd_in)) 1416a124edbaSYishai Hadas return -EINVAL; 1417a124edbaSYishai Hadas 1418a124edbaSYishai Hadas fd_uobj = uverbs_attr_get_uobject(attrs, 1419a124edbaSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_FD); 1420a124edbaSYishai Hadas if (IS_ERR(fd_uobj)) 1421a124edbaSYishai Hadas return PTR_ERR(fd_uobj); 1422a124edbaSYishai Hadas 1423a124edbaSYishai Hadas ev_file = container_of(fd_uobj, struct devx_async_cmd_event_file, 1424a124edbaSYishai Hadas uobj); 1425a124edbaSYishai Hadas 1426a124edbaSYishai Hadas if (atomic_add_return(cmd_out_len, &ev_file->ev_queue.bytes_in_use) > 1427a124edbaSYishai Hadas MAX_ASYNC_BYTES_IN_USE) { 1428a124edbaSYishai Hadas atomic_sub(cmd_out_len, &ev_file->ev_queue.bytes_in_use); 1429a124edbaSYishai Hadas return -EAGAIN; 1430a124edbaSYishai Hadas } 1431a124edbaSYishai Hadas 1432a124edbaSYishai Hadas async_data = kvzalloc(struct_size(async_data, hdr.out_data, 1433a124edbaSYishai Hadas cmd_out_len), GFP_KERNEL); 1434a124edbaSYishai Hadas if (!async_data) { 1435a124edbaSYishai Hadas err = -ENOMEM; 1436a124edbaSYishai Hadas goto sub_bytes; 1437a124edbaSYishai Hadas } 1438a124edbaSYishai Hadas 1439a124edbaSYishai Hadas err = uverbs_copy_from(&async_data->hdr.wr_id, attrs, 1440a124edbaSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_WR_ID); 1441a124edbaSYishai Hadas if (err) 1442a124edbaSYishai Hadas goto free_async; 1443a124edbaSYishai Hadas 1444a124edbaSYishai Hadas async_data->cmd_out_len = cmd_out_len; 1445a124edbaSYishai Hadas async_data->mdev = mdev; 1446a124edbaSYishai Hadas async_data->fd_uobj = fd_uobj; 1447a124edbaSYishai Hadas 1448a124edbaSYishai Hadas get_file(fd_uobj->object); 1449a124edbaSYishai Hadas MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 1450a124edbaSYishai Hadas err = mlx5_cmd_exec_cb(&ev_file->async_ctx, cmd_in, 1451a124edbaSYishai Hadas uverbs_attr_get_len(attrs, 1452a124edbaSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN), 1453a124edbaSYishai Hadas async_data->hdr.out_data, 1454a124edbaSYishai Hadas async_data->cmd_out_len, 1455a124edbaSYishai Hadas devx_query_callback, &async_data->cb_work); 1456a124edbaSYishai Hadas 1457a124edbaSYishai Hadas if (err) 1458a124edbaSYishai Hadas goto cb_err; 1459a124edbaSYishai Hadas 1460a124edbaSYishai Hadas return 0; 1461a124edbaSYishai Hadas 1462a124edbaSYishai Hadas cb_err: 1463a124edbaSYishai Hadas fput(fd_uobj->object); 1464a124edbaSYishai Hadas free_async: 1465a124edbaSYishai Hadas kvfree(async_data); 1466a124edbaSYishai Hadas sub_bytes: 1467a124edbaSYishai Hadas atomic_sub(cmd_out_len, &ev_file->ev_queue.bytes_in_use); 1468a124edbaSYishai Hadas return err; 1469a124edbaSYishai Hadas } 1470a124edbaSYishai Hadas 1471aeae9457SYishai Hadas static int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext, 1472aeae9457SYishai Hadas struct uverbs_attr_bundle *attrs, 1473aeae9457SYishai Hadas struct devx_umem *obj) 1474aeae9457SYishai Hadas { 1475aeae9457SYishai Hadas u64 addr; 1476aeae9457SYishai Hadas size_t size; 1477bccd0622SJason Gunthorpe u32 access; 1478aeae9457SYishai Hadas int npages; 1479aeae9457SYishai Hadas int err; 1480aeae9457SYishai Hadas u32 page_mask; 1481aeae9457SYishai Hadas 1482aeae9457SYishai Hadas if (uverbs_copy_from(&addr, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR) || 1483bccd0622SJason Gunthorpe uverbs_copy_from(&size, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_LEN)) 1484aeae9457SYishai Hadas return -EFAULT; 1485aeae9457SYishai Hadas 1486bccd0622SJason Gunthorpe err = uverbs_get_flags32(&access, attrs, 1487bccd0622SJason Gunthorpe MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, 148847f07f03SYishai Hadas IB_ACCESS_LOCAL_WRITE | 148947f07f03SYishai Hadas IB_ACCESS_REMOTE_WRITE | 149047f07f03SYishai Hadas IB_ACCESS_REMOTE_READ); 1491bccd0622SJason Gunthorpe if (err) 1492bccd0622SJason Gunthorpe return err; 1493bccd0622SJason Gunthorpe 1494aeae9457SYishai Hadas err = ib_check_mr_access(access); 1495aeae9457SYishai Hadas if (err) 1496aeae9457SYishai Hadas return err; 1497aeae9457SYishai Hadas 1498b0ea0fa5SJason Gunthorpe obj->umem = ib_umem_get(&attrs->driver_udata, addr, size, access, 0); 1499aeae9457SYishai Hadas if (IS_ERR(obj->umem)) 1500aeae9457SYishai Hadas return PTR_ERR(obj->umem); 1501aeae9457SYishai Hadas 1502aeae9457SYishai Hadas mlx5_ib_cont_pages(obj->umem, obj->umem->address, 1503aeae9457SYishai Hadas MLX5_MKEY_PAGE_SHIFT_MASK, &npages, 1504aeae9457SYishai Hadas &obj->page_shift, &obj->ncont, NULL); 1505aeae9457SYishai Hadas 1506aeae9457SYishai Hadas if (!npages) { 1507aeae9457SYishai Hadas ib_umem_release(obj->umem); 1508aeae9457SYishai Hadas return -EINVAL; 1509aeae9457SYishai Hadas } 1510aeae9457SYishai Hadas 1511aeae9457SYishai Hadas page_mask = (1 << obj->page_shift) - 1; 1512aeae9457SYishai Hadas obj->page_offset = obj->umem->address & page_mask; 1513aeae9457SYishai Hadas 1514aeae9457SYishai Hadas return 0; 1515aeae9457SYishai Hadas } 1516aeae9457SYishai Hadas 1517b61815e2SJason Gunthorpe static int devx_umem_reg_cmd_alloc(struct uverbs_attr_bundle *attrs, 1518b61815e2SJason Gunthorpe struct devx_umem *obj, 1519aeae9457SYishai Hadas struct devx_umem_reg_cmd *cmd) 1520aeae9457SYishai Hadas { 1521aeae9457SYishai Hadas cmd->inlen = MLX5_ST_SZ_BYTES(create_umem_in) + 1522aeae9457SYishai Hadas (MLX5_ST_SZ_BYTES(mtt) * obj->ncont); 1523b61815e2SJason Gunthorpe cmd->in = uverbs_zalloc(attrs, cmd->inlen); 1524b61815e2SJason Gunthorpe return PTR_ERR_OR_ZERO(cmd->in); 1525aeae9457SYishai Hadas } 1526aeae9457SYishai Hadas 1527aeae9457SYishai Hadas static void devx_umem_reg_cmd_build(struct mlx5_ib_dev *dev, 1528aeae9457SYishai Hadas struct devx_umem *obj, 1529aeae9457SYishai Hadas struct devx_umem_reg_cmd *cmd) 1530aeae9457SYishai Hadas { 1531aeae9457SYishai Hadas void *umem; 1532aeae9457SYishai Hadas __be64 *mtt; 1533aeae9457SYishai Hadas 1534aeae9457SYishai Hadas umem = MLX5_ADDR_OF(create_umem_in, cmd->in, umem); 1535aeae9457SYishai Hadas mtt = (__be64 *)MLX5_ADDR_OF(umem, umem, mtt); 1536aeae9457SYishai Hadas 15376e3722baSYishai Hadas MLX5_SET(create_umem_in, cmd->in, opcode, MLX5_CMD_OP_CREATE_UMEM); 1538aeae9457SYishai Hadas MLX5_SET64(umem, umem, num_of_mtt, obj->ncont); 1539aeae9457SYishai Hadas MLX5_SET(umem, umem, log_page_size, obj->page_shift - 1540aeae9457SYishai Hadas MLX5_ADAPTER_PAGE_SHIFT); 1541aeae9457SYishai Hadas MLX5_SET(umem, umem, page_offset, obj->page_offset); 1542aeae9457SYishai Hadas mlx5_ib_populate_pas(dev, obj->umem, obj->page_shift, mtt, 1543aeae9457SYishai Hadas (obj->umem->writable ? MLX5_IB_MTT_WRITE : 0) | 1544aeae9457SYishai Hadas MLX5_IB_MTT_READ); 1545aeae9457SYishai Hadas } 1546aeae9457SYishai Hadas 1547e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_REG)( 154815a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 1549aeae9457SYishai Hadas { 1550aeae9457SYishai Hadas struct devx_umem_reg_cmd cmd; 1551aeae9457SYishai Hadas struct devx_umem *obj; 1552c36ee46dSJason Gunthorpe struct ib_uobject *uobj = uverbs_attr_get_uobject( 1553c36ee46dSJason Gunthorpe attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE); 1554aeae9457SYishai Hadas u32 obj_id; 155589944450SShamir Rabinovitch struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 155689944450SShamir Rabinovitch &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 1557c36ee46dSJason Gunthorpe struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 1558aeae9457SYishai Hadas int err; 1559aeae9457SYishai Hadas 1560aeae9457SYishai Hadas if (!c->devx_uid) 15617e1335a7SYishai Hadas return -EINVAL; 15627e1335a7SYishai Hadas 1563aeae9457SYishai Hadas obj = kzalloc(sizeof(struct devx_umem), GFP_KERNEL); 1564aeae9457SYishai Hadas if (!obj) 1565aeae9457SYishai Hadas return -ENOMEM; 1566aeae9457SYishai Hadas 1567aeae9457SYishai Hadas err = devx_umem_get(dev, &c->ibucontext, attrs, obj); 1568aeae9457SYishai Hadas if (err) 1569aeae9457SYishai Hadas goto err_obj_free; 1570aeae9457SYishai Hadas 1571b61815e2SJason Gunthorpe err = devx_umem_reg_cmd_alloc(attrs, obj, &cmd); 1572aeae9457SYishai Hadas if (err) 1573aeae9457SYishai Hadas goto err_umem_release; 1574aeae9457SYishai Hadas 1575aeae9457SYishai Hadas devx_umem_reg_cmd_build(dev, obj, &cmd); 1576aeae9457SYishai Hadas 15776e3722baSYishai Hadas MLX5_SET(create_umem_in, cmd.in, uid, c->devx_uid); 1578aeae9457SYishai Hadas err = mlx5_cmd_exec(dev->mdev, cmd.in, cmd.inlen, cmd.out, 1579aeae9457SYishai Hadas sizeof(cmd.out)); 1580aeae9457SYishai Hadas if (err) 1581b61815e2SJason Gunthorpe goto err_umem_release; 1582aeae9457SYishai Hadas 1583aeae9457SYishai Hadas obj->mdev = dev->mdev; 1584aeae9457SYishai Hadas uobj->object = obj; 1585aeae9457SYishai Hadas devx_obj_build_destroy_cmd(cmd.in, cmd.out, obj->dinbox, &obj->dinlen, &obj_id); 1586aeae9457SYishai Hadas err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, &obj_id, sizeof(obj_id)); 1587aeae9457SYishai Hadas if (err) 1588aeae9457SYishai Hadas goto err_umem_destroy; 1589aeae9457SYishai Hadas 1590aeae9457SYishai Hadas return 0; 1591aeae9457SYishai Hadas 1592aeae9457SYishai Hadas err_umem_destroy: 1593aeae9457SYishai Hadas mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, cmd.out, sizeof(cmd.out)); 1594aeae9457SYishai Hadas err_umem_release: 1595aeae9457SYishai Hadas ib_umem_release(obj->umem); 1596aeae9457SYishai Hadas err_obj_free: 1597aeae9457SYishai Hadas kfree(obj); 1598aeae9457SYishai Hadas return err; 1599aeae9457SYishai Hadas } 1600aeae9457SYishai Hadas 1601aeae9457SYishai Hadas static int devx_umem_cleanup(struct ib_uobject *uobject, 1602aeae9457SYishai Hadas enum rdma_remove_reason why) 1603aeae9457SYishai Hadas { 1604aeae9457SYishai Hadas struct devx_umem *obj = uobject->object; 1605aeae9457SYishai Hadas u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 1606aeae9457SYishai Hadas int err; 1607aeae9457SYishai Hadas 1608aeae9457SYishai Hadas err = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out)); 16091c77483eSYishai Hadas if (ib_is_destroy_retryable(err, why, uobject)) 1610aeae9457SYishai Hadas return err; 1611aeae9457SYishai Hadas 1612aeae9457SYishai Hadas ib_umem_release(obj->umem); 1613aeae9457SYishai Hadas kfree(obj); 1614aeae9457SYishai Hadas return 0; 1615aeae9457SYishai Hadas } 1616aeae9457SYishai Hadas 16176bf8f22aSYishai Hadas static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf, 16186bf8f22aSYishai Hadas size_t count, loff_t *pos) 16196bf8f22aSYishai Hadas { 16204accbb3fSYishai Hadas struct devx_async_cmd_event_file *comp_ev_file = filp->private_data; 16214accbb3fSYishai Hadas struct devx_async_event_queue *ev_queue = &comp_ev_file->ev_queue; 16224accbb3fSYishai Hadas struct devx_async_data *event; 16234accbb3fSYishai Hadas int ret = 0; 16244accbb3fSYishai Hadas size_t eventsz; 16254accbb3fSYishai Hadas 16264accbb3fSYishai Hadas spin_lock_irq(&ev_queue->lock); 16274accbb3fSYishai Hadas 16284accbb3fSYishai Hadas while (list_empty(&ev_queue->event_list)) { 16294accbb3fSYishai Hadas spin_unlock_irq(&ev_queue->lock); 16304accbb3fSYishai Hadas 16314accbb3fSYishai Hadas if (filp->f_flags & O_NONBLOCK) 16324accbb3fSYishai Hadas return -EAGAIN; 16334accbb3fSYishai Hadas 16344accbb3fSYishai Hadas if (wait_event_interruptible( 16354accbb3fSYishai Hadas ev_queue->poll_wait, 1636eaebaf77SYishai Hadas (!list_empty(&ev_queue->event_list) || 1637eaebaf77SYishai Hadas ev_queue->is_destroyed))) { 16384accbb3fSYishai Hadas return -ERESTARTSYS; 16394accbb3fSYishai Hadas } 1640eaebaf77SYishai Hadas 1641eaebaf77SYishai Hadas if (list_empty(&ev_queue->event_list) && 1642eaebaf77SYishai Hadas ev_queue->is_destroyed) 1643eaebaf77SYishai Hadas return -EIO; 1644eaebaf77SYishai Hadas 16454accbb3fSYishai Hadas spin_lock_irq(&ev_queue->lock); 16464accbb3fSYishai Hadas } 16474accbb3fSYishai Hadas 16484accbb3fSYishai Hadas event = list_entry(ev_queue->event_list.next, 16494accbb3fSYishai Hadas struct devx_async_data, list); 16504accbb3fSYishai Hadas eventsz = event->cmd_out_len + 16514accbb3fSYishai Hadas sizeof(struct mlx5_ib_uapi_devx_async_cmd_hdr); 16524accbb3fSYishai Hadas 16534accbb3fSYishai Hadas if (eventsz > count) { 16544accbb3fSYishai Hadas spin_unlock_irq(&ev_queue->lock); 16554accbb3fSYishai Hadas return -ENOSPC; 16564accbb3fSYishai Hadas } 16574accbb3fSYishai Hadas 16584accbb3fSYishai Hadas list_del(ev_queue->event_list.next); 16594accbb3fSYishai Hadas spin_unlock_irq(&ev_queue->lock); 16604accbb3fSYishai Hadas 16614accbb3fSYishai Hadas if (copy_to_user(buf, &event->hdr, eventsz)) 16624accbb3fSYishai Hadas ret = -EFAULT; 16634accbb3fSYishai Hadas else 16644accbb3fSYishai Hadas ret = eventsz; 16654accbb3fSYishai Hadas 16664accbb3fSYishai Hadas atomic_sub(event->cmd_out_len, &ev_queue->bytes_in_use); 16674accbb3fSYishai Hadas kvfree(event); 16684accbb3fSYishai Hadas return ret; 16696bf8f22aSYishai Hadas } 16706bf8f22aSYishai Hadas 16716bf8f22aSYishai Hadas static int devx_async_cmd_event_close(struct inode *inode, struct file *filp) 16726bf8f22aSYishai Hadas { 1673a124edbaSYishai Hadas struct ib_uobject *uobj = filp->private_data; 1674a124edbaSYishai Hadas struct devx_async_cmd_event_file *comp_ev_file = container_of( 1675a124edbaSYishai Hadas uobj, struct devx_async_cmd_event_file, uobj); 1676a124edbaSYishai Hadas struct devx_async_data *entry, *tmp; 1677a124edbaSYishai Hadas 1678a124edbaSYishai Hadas spin_lock_irq(&comp_ev_file->ev_queue.lock); 1679a124edbaSYishai Hadas list_for_each_entry_safe(entry, tmp, 1680a124edbaSYishai Hadas &comp_ev_file->ev_queue.event_list, list) 1681a124edbaSYishai Hadas kvfree(entry); 1682a124edbaSYishai Hadas spin_unlock_irq(&comp_ev_file->ev_queue.lock); 1683a124edbaSYishai Hadas 16846bf8f22aSYishai Hadas uverbs_close_fd(filp); 16856bf8f22aSYishai Hadas return 0; 16866bf8f22aSYishai Hadas } 16876bf8f22aSYishai Hadas 16886bf8f22aSYishai Hadas static __poll_t devx_async_cmd_event_poll(struct file *filp, 16896bf8f22aSYishai Hadas struct poll_table_struct *wait) 16906bf8f22aSYishai Hadas { 16914accbb3fSYishai Hadas struct devx_async_cmd_event_file *comp_ev_file = filp->private_data; 16924accbb3fSYishai Hadas struct devx_async_event_queue *ev_queue = &comp_ev_file->ev_queue; 16934accbb3fSYishai Hadas __poll_t pollflags = 0; 16944accbb3fSYishai Hadas 16954accbb3fSYishai Hadas poll_wait(filp, &ev_queue->poll_wait, wait); 16964accbb3fSYishai Hadas 16974accbb3fSYishai Hadas spin_lock_irq(&ev_queue->lock); 1698eaebaf77SYishai Hadas if (ev_queue->is_destroyed) 1699eaebaf77SYishai Hadas pollflags = EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; 1700eaebaf77SYishai Hadas else if (!list_empty(&ev_queue->event_list)) 17014accbb3fSYishai Hadas pollflags = EPOLLIN | EPOLLRDNORM; 17024accbb3fSYishai Hadas spin_unlock_irq(&ev_queue->lock); 17034accbb3fSYishai Hadas 17044accbb3fSYishai Hadas return pollflags; 17056bf8f22aSYishai Hadas } 17066bf8f22aSYishai Hadas 17076bf8f22aSYishai Hadas const struct file_operations devx_async_cmd_event_fops = { 17086bf8f22aSYishai Hadas .owner = THIS_MODULE, 17096bf8f22aSYishai Hadas .read = devx_async_cmd_event_read, 17106bf8f22aSYishai Hadas .poll = devx_async_cmd_event_poll, 17116bf8f22aSYishai Hadas .release = devx_async_cmd_event_close, 17126bf8f22aSYishai Hadas .llseek = no_llseek, 17136bf8f22aSYishai Hadas }; 17146bf8f22aSYishai Hadas 17156bf8f22aSYishai Hadas static int devx_hot_unplug_async_cmd_event_file(struct ib_uobject *uobj, 17166bf8f22aSYishai Hadas enum rdma_remove_reason why) 17176bf8f22aSYishai Hadas { 1718a124edbaSYishai Hadas struct devx_async_cmd_event_file *comp_ev_file = 1719a124edbaSYishai Hadas container_of(uobj, struct devx_async_cmd_event_file, 1720a124edbaSYishai Hadas uobj); 1721eaebaf77SYishai Hadas struct devx_async_event_queue *ev_queue = &comp_ev_file->ev_queue; 1722eaebaf77SYishai Hadas 1723eaebaf77SYishai Hadas spin_lock_irq(&ev_queue->lock); 1724eaebaf77SYishai Hadas ev_queue->is_destroyed = 1; 1725eaebaf77SYishai Hadas spin_unlock_irq(&ev_queue->lock); 1726eaebaf77SYishai Hadas 1727eaebaf77SYishai Hadas if (why == RDMA_REMOVE_DRIVER_REMOVE) 1728eaebaf77SYishai Hadas wake_up_interruptible(&ev_queue->poll_wait); 1729a124edbaSYishai Hadas 1730a124edbaSYishai Hadas mlx5_cmd_cleanup_async_ctx(&comp_ev_file->async_ctx); 17316bf8f22aSYishai Hadas return 0; 17326bf8f22aSYishai Hadas }; 17336bf8f22aSYishai Hadas 17349a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 17359a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_UMEM_REG, 17369a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE, 1737aeae9457SYishai Hadas MLX5_IB_OBJECT_DEVX_UMEM, 1738aeae9457SYishai Hadas UVERBS_ACCESS_NEW, 173983bb4442SJason Gunthorpe UA_MANDATORY), 17409a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR, 17419a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u64), 174283bb4442SJason Gunthorpe UA_MANDATORY), 17439a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_LEN, 17449a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u64), 174583bb4442SJason Gunthorpe UA_MANDATORY), 1746bccd0622SJason Gunthorpe UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, 1747bccd0622SJason Gunthorpe enum ib_access_flags), 17489a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, 17499a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 175083bb4442SJason Gunthorpe UA_MANDATORY)); 1751aeae9457SYishai Hadas 1752528922afSYishai Hadas DECLARE_UVERBS_NAMED_METHOD_DESTROY( 17539a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_UMEM_DEREG, 17549a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE, 1755aeae9457SYishai Hadas MLX5_IB_OBJECT_DEVX_UMEM, 1756aeae9457SYishai Hadas UVERBS_ACCESS_DESTROY, 175783bb4442SJason Gunthorpe UA_MANDATORY)); 1758aeae9457SYishai Hadas 17599a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 17609a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_QUERY_EQN, 17619a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC, 17629a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 176383bb4442SJason Gunthorpe UA_MANDATORY), 17649a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN, 17659a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 176683bb4442SJason Gunthorpe UA_MANDATORY)); 1767f6fe01b7SYishai Hadas 17689a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 17699a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_QUERY_UAR, 17709a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX, 17719a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 177283bb4442SJason Gunthorpe UA_MANDATORY), 17739a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, 17749a119cd5SJason Gunthorpe UVERBS_ATTR_TYPE(u32), 177583bb4442SJason Gunthorpe UA_MANDATORY)); 17767c043e90SYishai Hadas 17779a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 17789a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OTHER, 17799a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 17809a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OTHER_CMD_IN, 17818aa8c95cSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 178283bb4442SJason Gunthorpe UA_MANDATORY, 178383bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 17849a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 17859a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, 17867efce369SYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1787540cd692SJason Gunthorpe UA_MANDATORY)); 17887efce369SYishai Hadas 17899a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 17909a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_CREATE, 17919a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE, 17929a119cd5SJason Gunthorpe MLX5_IB_OBJECT_DEVX_OBJ, 17939a119cd5SJason Gunthorpe UVERBS_ACCESS_NEW, 179483bb4442SJason Gunthorpe UA_MANDATORY), 17959a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 17969a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN, 17979a119cd5SJason Gunthorpe UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 179883bb4442SJason Gunthorpe UA_MANDATORY, 179983bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 18009a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 18019a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, 18029a119cd5SJason Gunthorpe UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1803540cd692SJason Gunthorpe UA_MANDATORY)); 18049a119cd5SJason Gunthorpe 1805528922afSYishai Hadas DECLARE_UVERBS_NAMED_METHOD_DESTROY( 18069a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_DESTROY, 18079a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE, 18087efce369SYishai Hadas MLX5_IB_OBJECT_DEVX_OBJ, 18097efce369SYishai Hadas UVERBS_ACCESS_DESTROY, 181083bb4442SJason Gunthorpe UA_MANDATORY)); 18117efce369SYishai Hadas 18129a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 18139a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_MODIFY, 18149a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE, 181534613eb1SYishai Hadas UVERBS_IDR_ANY_OBJECT, 1816e662e14dSYishai Hadas UVERBS_ACCESS_WRITE, 181783bb4442SJason Gunthorpe UA_MANDATORY), 18189a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 18199a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, 1820e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 182183bb4442SJason Gunthorpe UA_MANDATORY, 182283bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 18239a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 18249a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 1825e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1826540cd692SJason Gunthorpe UA_MANDATORY)); 1827e662e14dSYishai Hadas 18289a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 18299a119cd5SJason Gunthorpe MLX5_IB_METHOD_DEVX_OBJ_QUERY, 18309a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE, 183134613eb1SYishai Hadas UVERBS_IDR_ANY_OBJECT, 1832e662e14dSYishai Hadas UVERBS_ACCESS_READ, 183383bb4442SJason Gunthorpe UA_MANDATORY), 18349a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_IN( 18359a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, 1836e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 183783bb4442SJason Gunthorpe UA_MANDATORY, 183883bb4442SJason Gunthorpe UA_ALLOC_AND_COPY), 18399a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT( 18409a119cd5SJason Gunthorpe MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, 1841e662e14dSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 1842540cd692SJason Gunthorpe UA_MANDATORY)); 1843e662e14dSYishai Hadas 1844a124edbaSYishai Hadas DECLARE_UVERBS_NAMED_METHOD( 1845a124edbaSYishai Hadas MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY, 1846a124edbaSYishai Hadas UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE, 1847a124edbaSYishai Hadas UVERBS_IDR_ANY_OBJECT, 1848a124edbaSYishai Hadas UVERBS_ACCESS_READ, 1849a124edbaSYishai Hadas UA_MANDATORY), 1850a124edbaSYishai Hadas UVERBS_ATTR_PTR_IN( 1851a124edbaSYishai Hadas MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, 1852a124edbaSYishai Hadas UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 1853a124edbaSYishai Hadas UA_MANDATORY, 1854a124edbaSYishai Hadas UA_ALLOC_AND_COPY), 1855a124edbaSYishai Hadas UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_OUT_LEN, 1856a124edbaSYishai Hadas u16, UA_MANDATORY), 1857a124edbaSYishai Hadas UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_FD, 1858a124edbaSYishai Hadas MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 1859a124edbaSYishai Hadas UVERBS_ACCESS_READ, 1860a124edbaSYishai Hadas UA_MANDATORY), 1861a124edbaSYishai Hadas UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_WR_ID, 1862a124edbaSYishai Hadas UVERBS_ATTR_TYPE(u64), 1863a124edbaSYishai Hadas UA_MANDATORY)); 1864a124edbaSYishai Hadas 18656c61d2a5SJason Gunthorpe DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX, 18667c043e90SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER), 1867f6fe01b7SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR), 1868f6fe01b7SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_EQN)); 18698aa8c95cSYishai Hadas 18706c61d2a5SJason Gunthorpe DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ, 18719a119cd5SJason Gunthorpe UVERBS_TYPE_ALLOC_IDR(devx_obj_cleanup), 18727efce369SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE), 1873e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY), 1874e662e14dSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY), 1875a124edbaSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY), 1876a124edbaSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY)); 18777efce369SYishai Hadas 18786c61d2a5SJason Gunthorpe DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM, 18799a119cd5SJason Gunthorpe UVERBS_TYPE_ALLOC_IDR(devx_umem_cleanup), 1880aeae9457SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG), 1881aeae9457SYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG)); 1882aeae9457SYishai Hadas 18836bf8f22aSYishai Hadas 18846bf8f22aSYishai Hadas DECLARE_UVERBS_NAMED_METHOD( 18856bf8f22aSYishai Hadas MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC, 18866bf8f22aSYishai Hadas UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_ASYNC_CMD_FD_ALLOC_HANDLE, 18876bf8f22aSYishai Hadas MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 18886bf8f22aSYishai Hadas UVERBS_ACCESS_NEW, 18896bf8f22aSYishai Hadas UA_MANDATORY)); 18906bf8f22aSYishai Hadas 18916bf8f22aSYishai Hadas DECLARE_UVERBS_NAMED_OBJECT( 18926bf8f22aSYishai Hadas MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 18936bf8f22aSYishai Hadas UVERBS_TYPE_ALLOC_FD(sizeof(struct devx_async_cmd_event_file), 18946bf8f22aSYishai Hadas devx_hot_unplug_async_cmd_event_file, 18956bf8f22aSYishai Hadas &devx_async_cmd_event_fops, "[devx_async_cmd]", 18966bf8f22aSYishai Hadas O_RDONLY), 18976bf8f22aSYishai Hadas &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC)); 18986bf8f22aSYishai Hadas 189936e235c8SJason Gunthorpe static bool devx_is_supported(struct ib_device *device) 1900c59450c4SYishai Hadas { 190136e235c8SJason Gunthorpe struct mlx5_ib_dev *dev = to_mdev(device); 190236e235c8SJason Gunthorpe 19036e3722baSYishai Hadas return !dev->rep && MLX5_CAP_GEN(dev->mdev, log_max_uctx); 1904c59450c4SYishai Hadas } 190536e235c8SJason Gunthorpe 19060cbf432dSJason Gunthorpe const struct uapi_definition mlx5_ib_devx_defs[] = { 190736e235c8SJason Gunthorpe UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 190836e235c8SJason Gunthorpe MLX5_IB_OBJECT_DEVX, 190936e235c8SJason Gunthorpe UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 191036e235c8SJason Gunthorpe UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 191136e235c8SJason Gunthorpe MLX5_IB_OBJECT_DEVX_OBJ, 191236e235c8SJason Gunthorpe UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 191336e235c8SJason Gunthorpe UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 191436e235c8SJason Gunthorpe MLX5_IB_OBJECT_DEVX_UMEM, 191536e235c8SJason Gunthorpe UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 19166bf8f22aSYishai Hadas UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 19176bf8f22aSYishai Hadas MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 19186bf8f22aSYishai Hadas UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 19190cbf432dSJason Gunthorpe {}, 19200cbf432dSJason Gunthorpe }; 1921