18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <rdma/ib_user_verbs.h> 78c2ecf20Sopenharmony_ci#include <rdma/ib_verbs.h> 88c2ecf20Sopenharmony_ci#include <rdma/uverbs_types.h> 98c2ecf20Sopenharmony_ci#include <rdma/uverbs_ioctl.h> 108c2ecf20Sopenharmony_ci#include <rdma/mlx5_user_ioctl_cmds.h> 118c2ecf20Sopenharmony_ci#include <rdma/mlx5_user_ioctl_verbs.h> 128c2ecf20Sopenharmony_ci#include <rdma/ib_umem.h> 138c2ecf20Sopenharmony_ci#include <rdma/uverbs_std_types.h> 148c2ecf20Sopenharmony_ci#include <linux/mlx5/driver.h> 158c2ecf20Sopenharmony_ci#include <linux/mlx5/fs.h> 168c2ecf20Sopenharmony_ci#include "mlx5_ib.h" 178c2ecf20Sopenharmony_ci#include "devx.h" 188c2ecf20Sopenharmony_ci#include "qp.h" 198c2ecf20Sopenharmony_ci#include <linux/xarray.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define UVERBS_MODULE_NAME mlx5_ib 228c2ecf20Sopenharmony_ci#include <rdma/uverbs_named_ioctl.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic void dispatch_event_fd(struct list_head *fd_list, const void *data); 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cienum devx_obj_flags { 278c2ecf20Sopenharmony_ci DEVX_OBJ_FLAGS_INDIRECT_MKEY = 1 << 0, 288c2ecf20Sopenharmony_ci DEVX_OBJ_FLAGS_DCT = 1 << 1, 298c2ecf20Sopenharmony_ci DEVX_OBJ_FLAGS_CQ = 1 << 2, 308c2ecf20Sopenharmony_ci}; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistruct devx_async_data { 338c2ecf20Sopenharmony_ci struct mlx5_ib_dev *mdev; 348c2ecf20Sopenharmony_ci struct list_head list; 358c2ecf20Sopenharmony_ci struct devx_async_cmd_event_file *ev_file; 368c2ecf20Sopenharmony_ci struct mlx5_async_work cb_work; 378c2ecf20Sopenharmony_ci u16 cmd_out_len; 388c2ecf20Sopenharmony_ci /* must be last field in this structure */ 398c2ecf20Sopenharmony_ci struct mlx5_ib_uapi_devx_async_cmd_hdr hdr; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistruct devx_async_event_data { 438c2ecf20Sopenharmony_ci struct list_head list; /* headed in ev_file->event_list */ 448c2ecf20Sopenharmony_ci struct mlx5_ib_uapi_devx_async_event_hdr hdr; 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* first level XA value data structure */ 488c2ecf20Sopenharmony_cistruct devx_event { 498c2ecf20Sopenharmony_ci struct xarray object_ids; /* second XA level, Key = object id */ 508c2ecf20Sopenharmony_ci struct list_head unaffiliated_list; 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/* second level XA value data structure */ 548c2ecf20Sopenharmony_cistruct devx_obj_event { 558c2ecf20Sopenharmony_ci struct rcu_head rcu; 568c2ecf20Sopenharmony_ci struct list_head obj_sub_list; 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistruct devx_event_subscription { 608c2ecf20Sopenharmony_ci struct list_head file_list; /* headed in ev_file-> 618c2ecf20Sopenharmony_ci * subscribed_events_list 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_ci struct list_head xa_list; /* headed in devx_event->unaffiliated_list or 648c2ecf20Sopenharmony_ci * devx_obj_event->obj_sub_list 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ci struct list_head obj_list; /* headed in devx_object */ 678c2ecf20Sopenharmony_ci struct list_head event_list; /* headed in ev_file->event_list or in 688c2ecf20Sopenharmony_ci * temp list via subscription 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci u8 is_cleaned:1; 728c2ecf20Sopenharmony_ci u32 xa_key_level1; 738c2ecf20Sopenharmony_ci u32 xa_key_level2; 748c2ecf20Sopenharmony_ci struct rcu_head rcu; 758c2ecf20Sopenharmony_ci u64 cookie; 768c2ecf20Sopenharmony_ci struct devx_async_event_file *ev_file; 778c2ecf20Sopenharmony_ci struct eventfd_ctx *eventfd; 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistruct devx_async_event_file { 818c2ecf20Sopenharmony_ci struct ib_uobject uobj; 828c2ecf20Sopenharmony_ci /* Head of events that are subscribed to this FD */ 838c2ecf20Sopenharmony_ci struct list_head subscribed_events_list; 848c2ecf20Sopenharmony_ci spinlock_t lock; 858c2ecf20Sopenharmony_ci wait_queue_head_t poll_wait; 868c2ecf20Sopenharmony_ci struct list_head event_list; 878c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev; 888c2ecf20Sopenharmony_ci u8 omit_data:1; 898c2ecf20Sopenharmony_ci u8 is_overflow_err:1; 908c2ecf20Sopenharmony_ci u8 is_destroyed:1; 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistruct devx_umem { 948c2ecf20Sopenharmony_ci struct mlx5_core_dev *mdev; 958c2ecf20Sopenharmony_ci struct ib_umem *umem; 968c2ecf20Sopenharmony_ci u32 page_offset; 978c2ecf20Sopenharmony_ci int page_shift; 988c2ecf20Sopenharmony_ci int ncont; 998c2ecf20Sopenharmony_ci u32 dinlen; 1008c2ecf20Sopenharmony_ci u32 dinbox[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)]; 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistruct devx_umem_reg_cmd { 1048c2ecf20Sopenharmony_ci void *in; 1058c2ecf20Sopenharmony_ci u32 inlen; 1068c2ecf20Sopenharmony_ci u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic struct mlx5_ib_ucontext * 1108c2ecf20Sopenharmony_cidevx_ufile2uctx(const struct uverbs_attr_bundle *attrs) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci return to_mucontext(ib_uverbs_get_ucontext(attrs)); 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ciint mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0}; 1188c2ecf20Sopenharmony_ci u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 1198c2ecf20Sopenharmony_ci void *uctx; 1208c2ecf20Sopenharmony_ci int err; 1218c2ecf20Sopenharmony_ci u16 uid; 1228c2ecf20Sopenharmony_ci u32 cap = 0; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci /* 0 means not supported */ 1258c2ecf20Sopenharmony_ci if (!MLX5_CAP_GEN(dev->mdev, log_max_uctx)) 1268c2ecf20Sopenharmony_ci return -EINVAL; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci uctx = MLX5_ADDR_OF(create_uctx_in, in, uctx); 1298c2ecf20Sopenharmony_ci if (is_user && capable(CAP_NET_RAW) && 1308c2ecf20Sopenharmony_ci (MLX5_CAP_GEN(dev->mdev, uctx_cap) & MLX5_UCTX_CAP_RAW_TX)) 1318c2ecf20Sopenharmony_ci cap |= MLX5_UCTX_CAP_RAW_TX; 1328c2ecf20Sopenharmony_ci if (is_user && capable(CAP_SYS_RAWIO) && 1338c2ecf20Sopenharmony_ci (MLX5_CAP_GEN(dev->mdev, uctx_cap) & 1348c2ecf20Sopenharmony_ci MLX5_UCTX_CAP_INTERNAL_DEV_RES)) 1358c2ecf20Sopenharmony_ci cap |= MLX5_UCTX_CAP_INTERNAL_DEV_RES; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci MLX5_SET(create_uctx_in, in, opcode, MLX5_CMD_OP_CREATE_UCTX); 1388c2ecf20Sopenharmony_ci MLX5_SET(uctx, uctx, cap, cap); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 1418c2ecf20Sopenharmony_ci if (err) 1428c2ecf20Sopenharmony_ci return err; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci uid = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 1458c2ecf20Sopenharmony_ci return uid; 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_civoid mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci u32 in[MLX5_ST_SZ_DW(destroy_uctx_in)] = {0}; 1518c2ecf20Sopenharmony_ci u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci MLX5_SET(destroy_uctx_in, in, opcode, MLX5_CMD_OP_DESTROY_UCTX); 1548c2ecf20Sopenharmony_ci MLX5_SET(destroy_uctx_in, in, uid, uid); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out)); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic bool is_legacy_unaffiliated_event_num(u16 event_num) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci switch (event_num) { 1628c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_PORT_CHANGE: 1638c2ecf20Sopenharmony_ci return true; 1648c2ecf20Sopenharmony_ci default: 1658c2ecf20Sopenharmony_ci return false; 1668c2ecf20Sopenharmony_ci } 1678c2ecf20Sopenharmony_ci} 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic bool is_legacy_obj_event_num(u16 event_num) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci switch (event_num) { 1728c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_PATH_MIG: 1738c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_COMM_EST: 1748c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SQ_DRAINED: 1758c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_LAST_WQE: 1768c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT: 1778c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_CQ_ERROR: 1788c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_CATAS_ERROR: 1798c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_PATH_MIG_FAILED: 1808c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR: 1818c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR: 1828c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR: 1838c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_DCT_DRAINED: 1848c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_COMP: 1858c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_DCT_KEY_VIOLATION: 1868c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_XRQ_ERROR: 1878c2ecf20Sopenharmony_ci return true; 1888c2ecf20Sopenharmony_ci default: 1898c2ecf20Sopenharmony_ci return false; 1908c2ecf20Sopenharmony_ci } 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic u16 get_legacy_obj_type(u16 opcode) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci switch (opcode) { 1968c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQ: 1978c2ecf20Sopenharmony_ci return MLX5_EVENT_QUEUE_TYPE_RQ; 1988c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_QP: 1998c2ecf20Sopenharmony_ci return MLX5_EVENT_QUEUE_TYPE_QP; 2008c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SQ: 2018c2ecf20Sopenharmony_ci return MLX5_EVENT_QUEUE_TYPE_SQ; 2028c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_DCT: 2038c2ecf20Sopenharmony_ci return MLX5_EVENT_QUEUE_TYPE_DCT; 2048c2ecf20Sopenharmony_ci default: 2058c2ecf20Sopenharmony_ci return 0; 2068c2ecf20Sopenharmony_ci } 2078c2ecf20Sopenharmony_ci} 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_cistatic u16 get_dec_obj_type(struct devx_obj *obj, u16 event_num) 2108c2ecf20Sopenharmony_ci{ 2118c2ecf20Sopenharmony_ci u16 opcode; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci opcode = (obj->obj_id >> 32) & 0xffff; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci if (is_legacy_obj_event_num(event_num)) 2168c2ecf20Sopenharmony_ci return get_legacy_obj_type(opcode); 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci switch (opcode) { 2198c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 2208c2ecf20Sopenharmony_ci return (obj->obj_id >> 48); 2218c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQ: 2228c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_RQ; 2238c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_QP: 2248c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_QP; 2258c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SQ: 2268c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_SQ; 2278c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_DCT: 2288c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_DCT; 2298c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_TIR: 2308c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_TIR; 2318c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_TIS: 2328c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_TIS; 2338c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_PSV: 2348c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_PSV; 2358c2ecf20Sopenharmony_ci case MLX5_OBJ_TYPE_MKEY: 2368c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_MKEY; 2378c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RMP: 2388c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_RMP; 2398c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRC_SRQ: 2408c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_XRC_SRQ; 2418c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRQ: 2428c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_XRQ; 2438c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQT: 2448c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_RQT; 2458c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 2468c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_FLOW_COUNTER; 2478c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_CQ: 2488c2ecf20Sopenharmony_ci return MLX5_OBJ_TYPE_CQ; 2498c2ecf20Sopenharmony_ci default: 2508c2ecf20Sopenharmony_ci return 0; 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic u16 get_event_obj_type(unsigned long event_type, struct mlx5_eqe *eqe) 2558c2ecf20Sopenharmony_ci{ 2568c2ecf20Sopenharmony_ci switch (event_type) { 2578c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_CATAS_ERROR: 2588c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR: 2598c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR: 2608c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_LAST_WQE: 2618c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_PATH_MIG: 2628c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_PATH_MIG_FAILED: 2638c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_COMM_EST: 2648c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SQ_DRAINED: 2658c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT: 2668c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR: 2678c2ecf20Sopenharmony_ci return eqe->data.qp_srq.type; 2688c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_CQ_ERROR: 2698c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_XRQ_ERROR: 2708c2ecf20Sopenharmony_ci return 0; 2718c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_DCT_DRAINED: 2728c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_DCT_KEY_VIOLATION: 2738c2ecf20Sopenharmony_ci return MLX5_EVENT_QUEUE_TYPE_DCT; 2748c2ecf20Sopenharmony_ci default: 2758c2ecf20Sopenharmony_ci return MLX5_GET(affiliated_event_header, &eqe->data, obj_type); 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci} 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cistatic u32 get_dec_obj_id(u64 obj_id) 2808c2ecf20Sopenharmony_ci{ 2818c2ecf20Sopenharmony_ci return (obj_id & 0xffffffff); 2828c2ecf20Sopenharmony_ci} 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci/* 2858c2ecf20Sopenharmony_ci * As the obj_id in the firmware is not globally unique the object type 2868c2ecf20Sopenharmony_ci * must be considered upon checking for a valid object id. 2878c2ecf20Sopenharmony_ci * For that the opcode of the creator command is encoded as part of the obj_id. 2888c2ecf20Sopenharmony_ci */ 2898c2ecf20Sopenharmony_cistatic u64 get_enc_obj_id(u32 opcode, u32 obj_id) 2908c2ecf20Sopenharmony_ci{ 2918c2ecf20Sopenharmony_ci return ((u64)opcode << 32) | obj_id; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic u64 devx_get_obj_id(const void *in) 2958c2ecf20Sopenharmony_ci{ 2968c2ecf20Sopenharmony_ci u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 2978c2ecf20Sopenharmony_ci u64 obj_id; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci switch (opcode) { 3008c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 3018c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 3028c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_GENERAL_OBJECT | 3038c2ecf20Sopenharmony_ci MLX5_GET(general_obj_in_cmd_hdr, in, 3048c2ecf20Sopenharmony_ci obj_type) << 16, 3058c2ecf20Sopenharmony_ci MLX5_GET(general_obj_in_cmd_hdr, in, 3068c2ecf20Sopenharmony_ci obj_id)); 3078c2ecf20Sopenharmony_ci break; 3088c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_MKEY: 3098c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_MKEY, 3108c2ecf20Sopenharmony_ci MLX5_GET(query_mkey_in, in, 3118c2ecf20Sopenharmony_ci mkey_index)); 3128c2ecf20Sopenharmony_ci break; 3138c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_CQ: 3148c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ, 3158c2ecf20Sopenharmony_ci MLX5_GET(query_cq_in, in, cqn)); 3168c2ecf20Sopenharmony_ci break; 3178c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_CQ: 3188c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ, 3198c2ecf20Sopenharmony_ci MLX5_GET(modify_cq_in, in, cqn)); 3208c2ecf20Sopenharmony_ci break; 3218c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_SQ: 3228c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ, 3238c2ecf20Sopenharmony_ci MLX5_GET(query_sq_in, in, sqn)); 3248c2ecf20Sopenharmony_ci break; 3258c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_SQ: 3268c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ, 3278c2ecf20Sopenharmony_ci MLX5_GET(modify_sq_in, in, sqn)); 3288c2ecf20Sopenharmony_ci break; 3298c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_RQ: 3308c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 3318c2ecf20Sopenharmony_ci MLX5_GET(query_rq_in, in, rqn)); 3328c2ecf20Sopenharmony_ci break; 3338c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_RQ: 3348c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 3358c2ecf20Sopenharmony_ci MLX5_GET(modify_rq_in, in, rqn)); 3368c2ecf20Sopenharmony_ci break; 3378c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_RMP: 3388c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP, 3398c2ecf20Sopenharmony_ci MLX5_GET(query_rmp_in, in, rmpn)); 3408c2ecf20Sopenharmony_ci break; 3418c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_RMP: 3428c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RMP, 3438c2ecf20Sopenharmony_ci MLX5_GET(modify_rmp_in, in, rmpn)); 3448c2ecf20Sopenharmony_ci break; 3458c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_RQT: 3468c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT, 3478c2ecf20Sopenharmony_ci MLX5_GET(query_rqt_in, in, rqtn)); 3488c2ecf20Sopenharmony_ci break; 3498c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_RQT: 3508c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT, 3518c2ecf20Sopenharmony_ci MLX5_GET(modify_rqt_in, in, rqtn)); 3528c2ecf20Sopenharmony_ci break; 3538c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_TIR: 3548c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR, 3558c2ecf20Sopenharmony_ci MLX5_GET(query_tir_in, in, tirn)); 3568c2ecf20Sopenharmony_ci break; 3578c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_TIR: 3588c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR, 3598c2ecf20Sopenharmony_ci MLX5_GET(modify_tir_in, in, tirn)); 3608c2ecf20Sopenharmony_ci break; 3618c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_TIS: 3628c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS, 3638c2ecf20Sopenharmony_ci MLX5_GET(query_tis_in, in, tisn)); 3648c2ecf20Sopenharmony_ci break; 3658c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_TIS: 3668c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS, 3678c2ecf20Sopenharmony_ci MLX5_GET(modify_tis_in, in, tisn)); 3688c2ecf20Sopenharmony_ci break; 3698c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_TABLE: 3708c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE, 3718c2ecf20Sopenharmony_ci MLX5_GET(query_flow_table_in, in, 3728c2ecf20Sopenharmony_ci table_id)); 3738c2ecf20Sopenharmony_ci break; 3748c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 3758c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_TABLE, 3768c2ecf20Sopenharmony_ci MLX5_GET(modify_flow_table_in, in, 3778c2ecf20Sopenharmony_ci table_id)); 3788c2ecf20Sopenharmony_ci break; 3798c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_GROUP: 3808c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_FLOW_GROUP, 3818c2ecf20Sopenharmony_ci MLX5_GET(query_flow_group_in, in, 3828c2ecf20Sopenharmony_ci group_id)); 3838c2ecf20Sopenharmony_ci break; 3848c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 3858c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY, 3868c2ecf20Sopenharmony_ci MLX5_GET(query_fte_in, in, 3878c2ecf20Sopenharmony_ci flow_index)); 3888c2ecf20Sopenharmony_ci break; 3898c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 3908c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY, 3918c2ecf20Sopenharmony_ci MLX5_GET(set_fte_in, in, flow_index)); 3928c2ecf20Sopenharmony_ci break; 3938c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_Q_COUNTER: 3948c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_Q_COUNTER, 3958c2ecf20Sopenharmony_ci MLX5_GET(query_q_counter_in, in, 3968c2ecf20Sopenharmony_ci counter_set_id)); 3978c2ecf20Sopenharmony_ci break; 3988c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 3998c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_FLOW_COUNTER, 4008c2ecf20Sopenharmony_ci MLX5_GET(query_flow_counter_in, in, 4018c2ecf20Sopenharmony_ci flow_counter_id)); 4028c2ecf20Sopenharmony_ci break; 4038c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 4048c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT, 4058c2ecf20Sopenharmony_ci MLX5_GET(general_obj_in_cmd_hdr, in, 4068c2ecf20Sopenharmony_ci obj_id)); 4078c2ecf20Sopenharmony_ci break; 4088c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 4098c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT, 4108c2ecf20Sopenharmony_ci MLX5_GET(query_scheduling_element_in, 4118c2ecf20Sopenharmony_ci in, scheduling_element_id)); 4128c2ecf20Sopenharmony_ci break; 4138c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 4148c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT, 4158c2ecf20Sopenharmony_ci MLX5_GET(modify_scheduling_element_in, 4168c2ecf20Sopenharmony_ci in, scheduling_element_id)); 4178c2ecf20Sopenharmony_ci break; 4188c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 4198c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT, 4208c2ecf20Sopenharmony_ci MLX5_GET(add_vxlan_udp_dport_in, in, 4218c2ecf20Sopenharmony_ci vxlan_udp_port)); 4228c2ecf20Sopenharmony_ci break; 4238c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 4248c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY, 4258c2ecf20Sopenharmony_ci MLX5_GET(query_l2_table_entry_in, in, 4268c2ecf20Sopenharmony_ci table_index)); 4278c2ecf20Sopenharmony_ci break; 4288c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 4298c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_SET_L2_TABLE_ENTRY, 4308c2ecf20Sopenharmony_ci MLX5_GET(set_l2_table_entry_in, in, 4318c2ecf20Sopenharmony_ci table_index)); 4328c2ecf20Sopenharmony_ci break; 4338c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_QP: 4348c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4358c2ecf20Sopenharmony_ci MLX5_GET(query_qp_in, in, qpn)); 4368c2ecf20Sopenharmony_ci break; 4378c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RST2INIT_QP: 4388c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4398c2ecf20Sopenharmony_ci MLX5_GET(rst2init_qp_in, in, qpn)); 4408c2ecf20Sopenharmony_ci break; 4418c2ecf20Sopenharmony_ci case MLX5_CMD_OP_INIT2INIT_QP: 4428c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4438c2ecf20Sopenharmony_ci MLX5_GET(init2init_qp_in, in, qpn)); 4448c2ecf20Sopenharmony_ci break; 4458c2ecf20Sopenharmony_ci case MLX5_CMD_OP_INIT2RTR_QP: 4468c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4478c2ecf20Sopenharmony_ci MLX5_GET(init2rtr_qp_in, in, qpn)); 4488c2ecf20Sopenharmony_ci break; 4498c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RTR2RTS_QP: 4508c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4518c2ecf20Sopenharmony_ci MLX5_GET(rtr2rts_qp_in, in, qpn)); 4528c2ecf20Sopenharmony_ci break; 4538c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RTS2RTS_QP: 4548c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4558c2ecf20Sopenharmony_ci MLX5_GET(rts2rts_qp_in, in, qpn)); 4568c2ecf20Sopenharmony_ci break; 4578c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SQERR2RTS_QP: 4588c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4598c2ecf20Sopenharmony_ci MLX5_GET(sqerr2rts_qp_in, in, qpn)); 4608c2ecf20Sopenharmony_ci break; 4618c2ecf20Sopenharmony_ci case MLX5_CMD_OP_2ERR_QP: 4628c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4638c2ecf20Sopenharmony_ci MLX5_GET(qp_2err_in, in, qpn)); 4648c2ecf20Sopenharmony_ci break; 4658c2ecf20Sopenharmony_ci case MLX5_CMD_OP_2RST_QP: 4668c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 4678c2ecf20Sopenharmony_ci MLX5_GET(qp_2rst_in, in, qpn)); 4688c2ecf20Sopenharmony_ci break; 4698c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_DCT: 4708c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT, 4718c2ecf20Sopenharmony_ci MLX5_GET(query_dct_in, in, dctn)); 4728c2ecf20Sopenharmony_ci break; 4738c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRQ: 4748c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRQ_DC_PARAMS_ENTRY: 4758c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRQ_ERROR_PARAMS: 4768c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ, 4778c2ecf20Sopenharmony_ci MLX5_GET(query_xrq_in, in, xrqn)); 4788c2ecf20Sopenharmony_ci break; 4798c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRC_SRQ: 4808c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ, 4818c2ecf20Sopenharmony_ci MLX5_GET(query_xrc_srq_in, in, 4828c2ecf20Sopenharmony_ci xrc_srqn)); 4838c2ecf20Sopenharmony_ci break; 4848c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_XRC_SRQ: 4858c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRC_SRQ, 4868c2ecf20Sopenharmony_ci MLX5_GET(arm_xrc_srq_in, in, xrc_srqn)); 4878c2ecf20Sopenharmony_ci break; 4888c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_SRQ: 4898c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_SRQ, 4908c2ecf20Sopenharmony_ci MLX5_GET(query_srq_in, in, srqn)); 4918c2ecf20Sopenharmony_ci break; 4928c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_RQ: 4938c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 4948c2ecf20Sopenharmony_ci MLX5_GET(arm_rq_in, in, srq_number)); 4958c2ecf20Sopenharmony_ci break; 4968c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 4978c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT, 4988c2ecf20Sopenharmony_ci MLX5_GET(drain_dct_in, in, dctn)); 4998c2ecf20Sopenharmony_ci break; 5008c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_XRQ: 5018c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY: 5028c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RELEASE_XRQ_ERROR: 5038c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_XRQ: 5048c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ, 5058c2ecf20Sopenharmony_ci MLX5_GET(arm_xrq_in, in, xrqn)); 5068c2ecf20Sopenharmony_ci break; 5078c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_PACKET_REFORMAT_CONTEXT: 5088c2ecf20Sopenharmony_ci obj_id = get_enc_obj_id 5098c2ecf20Sopenharmony_ci (MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT, 5108c2ecf20Sopenharmony_ci MLX5_GET(query_packet_reformat_context_in, 5118c2ecf20Sopenharmony_ci in, packet_reformat_id)); 5128c2ecf20Sopenharmony_ci break; 5138c2ecf20Sopenharmony_ci default: 5148c2ecf20Sopenharmony_ci obj_id = 0; 5158c2ecf20Sopenharmony_ci } 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci return obj_id; 5188c2ecf20Sopenharmony_ci} 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_cistatic bool devx_is_valid_obj_id(struct uverbs_attr_bundle *attrs, 5218c2ecf20Sopenharmony_ci struct ib_uobject *uobj, const void *in) 5228c2ecf20Sopenharmony_ci{ 5238c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev = mlx5_udata_to_mdev(&attrs->driver_udata); 5248c2ecf20Sopenharmony_ci u64 obj_id = devx_get_obj_id(in); 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci if (!obj_id) 5278c2ecf20Sopenharmony_ci return false; 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci switch (uobj_get_object_id(uobj)) { 5308c2ecf20Sopenharmony_ci case UVERBS_OBJECT_CQ: 5318c2ecf20Sopenharmony_ci return get_enc_obj_id(MLX5_CMD_OP_CREATE_CQ, 5328c2ecf20Sopenharmony_ci to_mcq(uobj->object)->mcq.cqn) == 5338c2ecf20Sopenharmony_ci obj_id; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci case UVERBS_OBJECT_SRQ: 5368c2ecf20Sopenharmony_ci { 5378c2ecf20Sopenharmony_ci struct mlx5_core_srq *srq = &(to_msrq(uobj->object)->msrq); 5388c2ecf20Sopenharmony_ci u16 opcode; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci switch (srq->common.res) { 5418c2ecf20Sopenharmony_ci case MLX5_RES_XSRQ: 5428c2ecf20Sopenharmony_ci opcode = MLX5_CMD_OP_CREATE_XRC_SRQ; 5438c2ecf20Sopenharmony_ci break; 5448c2ecf20Sopenharmony_ci case MLX5_RES_XRQ: 5458c2ecf20Sopenharmony_ci opcode = MLX5_CMD_OP_CREATE_XRQ; 5468c2ecf20Sopenharmony_ci break; 5478c2ecf20Sopenharmony_ci default: 5488c2ecf20Sopenharmony_ci if (!dev->mdev->issi) 5498c2ecf20Sopenharmony_ci opcode = MLX5_CMD_OP_CREATE_SRQ; 5508c2ecf20Sopenharmony_ci else 5518c2ecf20Sopenharmony_ci opcode = MLX5_CMD_OP_CREATE_RMP; 5528c2ecf20Sopenharmony_ci } 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci return get_enc_obj_id(opcode, 5558c2ecf20Sopenharmony_ci to_msrq(uobj->object)->msrq.srqn) == 5568c2ecf20Sopenharmony_ci obj_id; 5578c2ecf20Sopenharmony_ci } 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci case UVERBS_OBJECT_QP: 5608c2ecf20Sopenharmony_ci { 5618c2ecf20Sopenharmony_ci struct mlx5_ib_qp *qp = to_mqp(uobj->object); 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci if (qp->type == IB_QPT_RAW_PACKET || 5648c2ecf20Sopenharmony_ci (qp->flags & IB_QP_CREATE_SOURCE_QPN)) { 5658c2ecf20Sopenharmony_ci struct mlx5_ib_raw_packet_qp *raw_packet_qp = 5668c2ecf20Sopenharmony_ci &qp->raw_packet_qp; 5678c2ecf20Sopenharmony_ci struct mlx5_ib_rq *rq = &raw_packet_qp->rq; 5688c2ecf20Sopenharmony_ci struct mlx5_ib_sq *sq = &raw_packet_qp->sq; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci return (get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 5718c2ecf20Sopenharmony_ci rq->base.mqp.qpn) == obj_id || 5728c2ecf20Sopenharmony_ci get_enc_obj_id(MLX5_CMD_OP_CREATE_SQ, 5738c2ecf20Sopenharmony_ci sq->base.mqp.qpn) == obj_id || 5748c2ecf20Sopenharmony_ci get_enc_obj_id(MLX5_CMD_OP_CREATE_TIR, 5758c2ecf20Sopenharmony_ci rq->tirn) == obj_id || 5768c2ecf20Sopenharmony_ci get_enc_obj_id(MLX5_CMD_OP_CREATE_TIS, 5778c2ecf20Sopenharmony_ci sq->tisn) == obj_id); 5788c2ecf20Sopenharmony_ci } 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci if (qp->type == MLX5_IB_QPT_DCT) 5818c2ecf20Sopenharmony_ci return get_enc_obj_id(MLX5_CMD_OP_CREATE_DCT, 5828c2ecf20Sopenharmony_ci qp->dct.mdct.mqp.qpn) == obj_id; 5838c2ecf20Sopenharmony_ci return get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, 5848c2ecf20Sopenharmony_ci qp->ibqp.qp_num) == obj_id; 5858c2ecf20Sopenharmony_ci } 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci case UVERBS_OBJECT_WQ: 5888c2ecf20Sopenharmony_ci return get_enc_obj_id(MLX5_CMD_OP_CREATE_RQ, 5898c2ecf20Sopenharmony_ci to_mrwq(uobj->object)->core_qp.qpn) == 5908c2ecf20Sopenharmony_ci obj_id; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci case UVERBS_OBJECT_RWQ_IND_TBL: 5938c2ecf20Sopenharmony_ci return get_enc_obj_id(MLX5_CMD_OP_CREATE_RQT, 5948c2ecf20Sopenharmony_ci to_mrwq_ind_table(uobj->object)->rqtn) == 5958c2ecf20Sopenharmony_ci obj_id; 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci case MLX5_IB_OBJECT_DEVX_OBJ: 5988c2ecf20Sopenharmony_ci { 5998c2ecf20Sopenharmony_ci u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 6008c2ecf20Sopenharmony_ci struct devx_obj *devx_uobj = uobj->object; 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci if (opcode == MLX5_CMD_OP_QUERY_FLOW_COUNTER && 6038c2ecf20Sopenharmony_ci devx_uobj->flow_counter_bulk_size) { 6048c2ecf20Sopenharmony_ci u64 end; 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci end = devx_uobj->obj_id + 6078c2ecf20Sopenharmony_ci devx_uobj->flow_counter_bulk_size; 6088c2ecf20Sopenharmony_ci return devx_uobj->obj_id <= obj_id && end > obj_id; 6098c2ecf20Sopenharmony_ci } 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci return devx_uobj->obj_id == obj_id; 6128c2ecf20Sopenharmony_ci } 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci default: 6158c2ecf20Sopenharmony_ci return false; 6168c2ecf20Sopenharmony_ci } 6178c2ecf20Sopenharmony_ci} 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_cistatic void devx_set_umem_valid(const void *in) 6208c2ecf20Sopenharmony_ci{ 6218c2ecf20Sopenharmony_ci u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci switch (opcode) { 6248c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_MKEY: 6258c2ecf20Sopenharmony_ci MLX5_SET(create_mkey_in, in, mkey_umem_valid, 1); 6268c2ecf20Sopenharmony_ci break; 6278c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_CQ: 6288c2ecf20Sopenharmony_ci { 6298c2ecf20Sopenharmony_ci void *cqc; 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci MLX5_SET(create_cq_in, in, cq_umem_valid, 1); 6328c2ecf20Sopenharmony_ci cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context); 6338c2ecf20Sopenharmony_ci MLX5_SET(cqc, cqc, dbr_umem_valid, 1); 6348c2ecf20Sopenharmony_ci break; 6358c2ecf20Sopenharmony_ci } 6368c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_QP: 6378c2ecf20Sopenharmony_ci { 6388c2ecf20Sopenharmony_ci void *qpc; 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); 6418c2ecf20Sopenharmony_ci MLX5_SET(qpc, qpc, dbr_umem_valid, 1); 6428c2ecf20Sopenharmony_ci MLX5_SET(create_qp_in, in, wq_umem_valid, 1); 6438c2ecf20Sopenharmony_ci break; 6448c2ecf20Sopenharmony_ci } 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQ: 6478c2ecf20Sopenharmony_ci { 6488c2ecf20Sopenharmony_ci void *rqc, *wq; 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci rqc = MLX5_ADDR_OF(create_rq_in, in, ctx); 6518c2ecf20Sopenharmony_ci wq = MLX5_ADDR_OF(rqc, rqc, wq); 6528c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, dbr_umem_valid, 1); 6538c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, wq_umem_valid, 1); 6548c2ecf20Sopenharmony_ci break; 6558c2ecf20Sopenharmony_ci } 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SQ: 6588c2ecf20Sopenharmony_ci { 6598c2ecf20Sopenharmony_ci void *sqc, *wq; 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_ci sqc = MLX5_ADDR_OF(create_sq_in, in, ctx); 6628c2ecf20Sopenharmony_ci wq = MLX5_ADDR_OF(sqc, sqc, wq); 6638c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, dbr_umem_valid, 1); 6648c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, wq_umem_valid, 1); 6658c2ecf20Sopenharmony_ci break; 6668c2ecf20Sopenharmony_ci } 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_CQ: 6698c2ecf20Sopenharmony_ci MLX5_SET(modify_cq_in, in, cq_umem_valid, 1); 6708c2ecf20Sopenharmony_ci break; 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RMP: 6738c2ecf20Sopenharmony_ci { 6748c2ecf20Sopenharmony_ci void *rmpc, *wq; 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci rmpc = MLX5_ADDR_OF(create_rmp_in, in, ctx); 6778c2ecf20Sopenharmony_ci wq = MLX5_ADDR_OF(rmpc, rmpc, wq); 6788c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, dbr_umem_valid, 1); 6798c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, wq_umem_valid, 1); 6808c2ecf20Sopenharmony_ci break; 6818c2ecf20Sopenharmony_ci } 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRQ: 6848c2ecf20Sopenharmony_ci { 6858c2ecf20Sopenharmony_ci void *xrqc, *wq; 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_ci xrqc = MLX5_ADDR_OF(create_xrq_in, in, xrq_context); 6888c2ecf20Sopenharmony_ci wq = MLX5_ADDR_OF(xrqc, xrqc, wq); 6898c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, dbr_umem_valid, 1); 6908c2ecf20Sopenharmony_ci MLX5_SET(wq, wq, wq_umem_valid, 1); 6918c2ecf20Sopenharmony_ci break; 6928c2ecf20Sopenharmony_ci } 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRC_SRQ: 6958c2ecf20Sopenharmony_ci { 6968c2ecf20Sopenharmony_ci void *xrc_srqc; 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_ci MLX5_SET(create_xrc_srq_in, in, xrc_srq_umem_valid, 1); 6998c2ecf20Sopenharmony_ci xrc_srqc = MLX5_ADDR_OF(create_xrc_srq_in, in, 7008c2ecf20Sopenharmony_ci xrc_srq_context_entry); 7018c2ecf20Sopenharmony_ci MLX5_SET(xrc_srqc, xrc_srqc, dbr_umem_valid, 1); 7028c2ecf20Sopenharmony_ci break; 7038c2ecf20Sopenharmony_ci } 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci default: 7068c2ecf20Sopenharmony_ci return; 7078c2ecf20Sopenharmony_ci } 7088c2ecf20Sopenharmony_ci} 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_cistatic bool devx_is_obj_create_cmd(const void *in, u16 *opcode) 7118c2ecf20Sopenharmony_ci{ 7128c2ecf20Sopenharmony_ci *opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci switch (*opcode) { 7158c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 7168c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_MKEY: 7178c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_CQ: 7188c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_PD: 7198c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 7208c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RMP: 7218c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SQ: 7228c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQ: 7238c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQT: 7248c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_TIR: 7258c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_TIS: 7268c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_Q_COUNTER: 7278c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_FLOW_TABLE: 7288c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_FLOW_GROUP: 7298c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 7308c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT: 7318c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 7328c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 7338c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 7348c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 7358c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_QP: 7368c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SRQ: 7378c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRC_SRQ: 7388c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_DCT: 7398c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRQ: 7408c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ATTACH_TO_MCG: 7418c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_XRCD: 7428c2ecf20Sopenharmony_ci return true; 7438c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 7448c2ecf20Sopenharmony_ci { 7458c2ecf20Sopenharmony_ci u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 7468c2ecf20Sopenharmony_ci if (op_mod == 0) 7478c2ecf20Sopenharmony_ci return true; 7488c2ecf20Sopenharmony_ci return false; 7498c2ecf20Sopenharmony_ci } 7508c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_PSV: 7518c2ecf20Sopenharmony_ci { 7528c2ecf20Sopenharmony_ci u8 num_psv = MLX5_GET(create_psv_in, in, num_psv); 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci if (num_psv == 1) 7558c2ecf20Sopenharmony_ci return true; 7568c2ecf20Sopenharmony_ci return false; 7578c2ecf20Sopenharmony_ci } 7588c2ecf20Sopenharmony_ci default: 7598c2ecf20Sopenharmony_ci return false; 7608c2ecf20Sopenharmony_ci } 7618c2ecf20Sopenharmony_ci} 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_cistatic bool devx_is_obj_modify_cmd(const void *in) 7648c2ecf20Sopenharmony_ci{ 7658c2ecf20Sopenharmony_ci u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci switch (opcode) { 7688c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: 7698c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_CQ: 7708c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_RMP: 7718c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_SQ: 7728c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_RQ: 7738c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_RQT: 7748c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_TIR: 7758c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_TIS: 7768c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_FLOW_TABLE: 7778c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_SCHEDULING_ELEMENT: 7788c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 7798c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 7808c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RST2INIT_QP: 7818c2ecf20Sopenharmony_ci case MLX5_CMD_OP_INIT2RTR_QP: 7828c2ecf20Sopenharmony_ci case MLX5_CMD_OP_INIT2INIT_QP: 7838c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RTR2RTS_QP: 7848c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RTS2RTS_QP: 7858c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SQERR2RTS_QP: 7868c2ecf20Sopenharmony_ci case MLX5_CMD_OP_2ERR_QP: 7878c2ecf20Sopenharmony_ci case MLX5_CMD_OP_2RST_QP: 7888c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_XRC_SRQ: 7898c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_RQ: 7908c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION: 7918c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ARM_XRQ: 7928c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY: 7938c2ecf20Sopenharmony_ci case MLX5_CMD_OP_RELEASE_XRQ_ERROR: 7948c2ecf20Sopenharmony_ci case MLX5_CMD_OP_MODIFY_XRQ: 7958c2ecf20Sopenharmony_ci return true; 7968c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 7978c2ecf20Sopenharmony_ci { 7988c2ecf20Sopenharmony_ci u16 op_mod = MLX5_GET(set_fte_in, in, op_mod); 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci if (op_mod == 1) 8018c2ecf20Sopenharmony_ci return true; 8028c2ecf20Sopenharmony_ci return false; 8038c2ecf20Sopenharmony_ci } 8048c2ecf20Sopenharmony_ci default: 8058c2ecf20Sopenharmony_ci return false; 8068c2ecf20Sopenharmony_ci } 8078c2ecf20Sopenharmony_ci} 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_cistatic bool devx_is_obj_query_cmd(const void *in) 8108c2ecf20Sopenharmony_ci{ 8118c2ecf20Sopenharmony_ci u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci switch (opcode) { 8148c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: 8158c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_MKEY: 8168c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_CQ: 8178c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_RMP: 8188c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_SQ: 8198c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_RQ: 8208c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_RQT: 8218c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_TIR: 8228c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_TIS: 8238c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_Q_COUNTER: 8248c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_TABLE: 8258c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_GROUP: 8268c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY: 8278c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_FLOW_COUNTER: 8288c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT: 8298c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT: 8308c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_L2_TABLE_ENTRY: 8318c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_QP: 8328c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_SRQ: 8338c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRC_SRQ: 8348c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_DCT: 8358c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRQ: 8368c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRQ_DC_PARAMS_ENTRY: 8378c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_XRQ_ERROR_PARAMS: 8388c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_PACKET_REFORMAT_CONTEXT: 8398c2ecf20Sopenharmony_ci return true; 8408c2ecf20Sopenharmony_ci default: 8418c2ecf20Sopenharmony_ci return false; 8428c2ecf20Sopenharmony_ci } 8438c2ecf20Sopenharmony_ci} 8448c2ecf20Sopenharmony_ci 8458c2ecf20Sopenharmony_cistatic bool devx_is_whitelist_cmd(void *in) 8468c2ecf20Sopenharmony_ci{ 8478c2ecf20Sopenharmony_ci u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ci switch (opcode) { 8508c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_HCA_CAP: 8518c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT: 8528c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT: 8538c2ecf20Sopenharmony_ci return true; 8548c2ecf20Sopenharmony_ci default: 8558c2ecf20Sopenharmony_ci return false; 8568c2ecf20Sopenharmony_ci } 8578c2ecf20Sopenharmony_ci} 8588c2ecf20Sopenharmony_ci 8598c2ecf20Sopenharmony_cistatic int devx_get_uid(struct mlx5_ib_ucontext *c, void *cmd_in) 8608c2ecf20Sopenharmony_ci{ 8618c2ecf20Sopenharmony_ci if (devx_is_whitelist_cmd(cmd_in)) { 8628c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev; 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci if (c->devx_uid) 8658c2ecf20Sopenharmony_ci return c->devx_uid; 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci dev = to_mdev(c->ibucontext.device); 8688c2ecf20Sopenharmony_ci if (dev->devx_whitelist_uid) 8698c2ecf20Sopenharmony_ci return dev->devx_whitelist_uid; 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 8728c2ecf20Sopenharmony_ci } 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_ci if (!c->devx_uid) 8758c2ecf20Sopenharmony_ci return -EINVAL; 8768c2ecf20Sopenharmony_ci 8778c2ecf20Sopenharmony_ci return c->devx_uid; 8788c2ecf20Sopenharmony_ci} 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_cistatic bool devx_is_general_cmd(void *in, struct mlx5_ib_dev *dev) 8818c2ecf20Sopenharmony_ci{ 8828c2ecf20Sopenharmony_ci u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci /* Pass all cmds for vhca_tunnel as general, tracking is done in FW */ 8858c2ecf20Sopenharmony_ci if ((MLX5_CAP_GEN_64(dev->mdev, vhca_tunnel_commands) && 8868c2ecf20Sopenharmony_ci MLX5_GET(general_obj_in_cmd_hdr, in, vhca_tunnel_id)) || 8878c2ecf20Sopenharmony_ci (opcode >= MLX5_CMD_OP_GENERAL_START && 8888c2ecf20Sopenharmony_ci opcode < MLX5_CMD_OP_GENERAL_END)) 8898c2ecf20Sopenharmony_ci return true; 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci switch (opcode) { 8928c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_HCA_CAP: 8938c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT: 8948c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT: 8958c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_VPORT_STATE: 8968c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_ADAPTER: 8978c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_ISSI: 8988c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT: 8998c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_ROCE_ADDRESS: 9008c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_VNIC_ENV: 9018c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_VPORT_COUNTER: 9028c2ecf20Sopenharmony_ci case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG: 9038c2ecf20Sopenharmony_ci case MLX5_CMD_OP_NOP: 9048c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_CONG_STATUS: 9058c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_CONG_PARAMS: 9068c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_CONG_STATISTICS: 9078c2ecf20Sopenharmony_ci case MLX5_CMD_OP_QUERY_LAG: 9088c2ecf20Sopenharmony_ci return true; 9098c2ecf20Sopenharmony_ci default: 9108c2ecf20Sopenharmony_ci return false; 9118c2ecf20Sopenharmony_ci } 9128c2ecf20Sopenharmony_ci} 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_EQN)( 9158c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 9168c2ecf20Sopenharmony_ci{ 9178c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c; 9188c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev; 9198c2ecf20Sopenharmony_ci int user_vector; 9208c2ecf20Sopenharmony_ci int dev_eqn; 9218c2ecf20Sopenharmony_ci int err; 9228c2ecf20Sopenharmony_ci 9238c2ecf20Sopenharmony_ci if (uverbs_copy_from(&user_vector, attrs, 9248c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC)) 9258c2ecf20Sopenharmony_ci return -EFAULT; 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_ci c = devx_ufile2uctx(attrs); 9288c2ecf20Sopenharmony_ci if (IS_ERR(c)) 9298c2ecf20Sopenharmony_ci return PTR_ERR(c); 9308c2ecf20Sopenharmony_ci dev = to_mdev(c->ibucontext.device); 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci err = mlx5_vector2eqn(dev->mdev, user_vector, &dev_eqn); 9338c2ecf20Sopenharmony_ci if (err < 0) 9348c2ecf20Sopenharmony_ci return err; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN, 9378c2ecf20Sopenharmony_ci &dev_eqn, sizeof(dev_eqn))) 9388c2ecf20Sopenharmony_ci return -EFAULT; 9398c2ecf20Sopenharmony_ci 9408c2ecf20Sopenharmony_ci return 0; 9418c2ecf20Sopenharmony_ci} 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci/* 9448c2ecf20Sopenharmony_ci *Security note: 9458c2ecf20Sopenharmony_ci * The hardware protection mechanism works like this: Each device object that 9468c2ecf20Sopenharmony_ci * is subject to UAR doorbells (QP/SQ/CQ) gets a UAR ID (called uar_page in 9478c2ecf20Sopenharmony_ci * the device specification manual) upon its creation. Then upon doorbell, 9488c2ecf20Sopenharmony_ci * hardware fetches the object context for which the doorbell was rang, and 9498c2ecf20Sopenharmony_ci * validates that the UAR through which the DB was rang matches the UAR ID 9508c2ecf20Sopenharmony_ci * of the object. 9518c2ecf20Sopenharmony_ci * If no match the doorbell is silently ignored by the hardware. Of course, 9528c2ecf20Sopenharmony_ci * the user cannot ring a doorbell on a UAR that was not mapped to it. 9538c2ecf20Sopenharmony_ci * Now in devx, as the devx kernel does not manipulate the QP/SQ/CQ command 9548c2ecf20Sopenharmony_ci * mailboxes (except tagging them with UID), we expose to the user its UAR 9558c2ecf20Sopenharmony_ci * ID, so it can embed it in these objects in the expected specification 9568c2ecf20Sopenharmony_ci * format. So the only thing the user can do is hurt itself by creating a 9578c2ecf20Sopenharmony_ci * QP/SQ/CQ with a UAR ID other than his, and then in this case other users 9588c2ecf20Sopenharmony_ci * may ring a doorbell on its objects. 9598c2ecf20Sopenharmony_ci * The consequence of that will be that another user can schedule a QP/SQ 9608c2ecf20Sopenharmony_ci * of the buggy user for execution (just insert it to the hardware schedule 9618c2ecf20Sopenharmony_ci * queue or arm its CQ for event generation), no further harm is expected. 9628c2ecf20Sopenharmony_ci */ 9638c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_UAR)( 9648c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 9658c2ecf20Sopenharmony_ci{ 9668c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c; 9678c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev; 9688c2ecf20Sopenharmony_ci u32 user_idx; 9698c2ecf20Sopenharmony_ci s32 dev_idx; 9708c2ecf20Sopenharmony_ci 9718c2ecf20Sopenharmony_ci c = devx_ufile2uctx(attrs); 9728c2ecf20Sopenharmony_ci if (IS_ERR(c)) 9738c2ecf20Sopenharmony_ci return PTR_ERR(c); 9748c2ecf20Sopenharmony_ci dev = to_mdev(c->ibucontext.device); 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ci if (uverbs_copy_from(&user_idx, attrs, 9778c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX)) 9788c2ecf20Sopenharmony_ci return -EFAULT; 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci dev_idx = bfregn_to_uar_index(dev, &c->bfregi, user_idx, true); 9818c2ecf20Sopenharmony_ci if (dev_idx < 0) 9828c2ecf20Sopenharmony_ci return dev_idx; 9838c2ecf20Sopenharmony_ci 9848c2ecf20Sopenharmony_ci if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, 9858c2ecf20Sopenharmony_ci &dev_idx, sizeof(dev_idx))) 9868c2ecf20Sopenharmony_ci return -EFAULT; 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci return 0; 9898c2ecf20Sopenharmony_ci} 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)( 9928c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 9938c2ecf20Sopenharmony_ci{ 9948c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c; 9958c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev; 9968c2ecf20Sopenharmony_ci void *cmd_in = uverbs_attr_get_alloced_ptr( 9978c2ecf20Sopenharmony_ci attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN); 9988c2ecf20Sopenharmony_ci int cmd_out_len = uverbs_attr_get_len(attrs, 9998c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT); 10008c2ecf20Sopenharmony_ci void *cmd_out; 10018c2ecf20Sopenharmony_ci int err; 10028c2ecf20Sopenharmony_ci int uid; 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci c = devx_ufile2uctx(attrs); 10058c2ecf20Sopenharmony_ci if (IS_ERR(c)) 10068c2ecf20Sopenharmony_ci return PTR_ERR(c); 10078c2ecf20Sopenharmony_ci dev = to_mdev(c->ibucontext.device); 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci uid = devx_get_uid(c, cmd_in); 10108c2ecf20Sopenharmony_ci if (uid < 0) 10118c2ecf20Sopenharmony_ci return uid; 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci /* Only white list of some general HCA commands are allowed for this method. */ 10148c2ecf20Sopenharmony_ci if (!devx_is_general_cmd(cmd_in, dev)) 10158c2ecf20Sopenharmony_ci return -EINVAL; 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_ci cmd_out = uverbs_zalloc(attrs, cmd_out_len); 10188c2ecf20Sopenharmony_ci if (IS_ERR(cmd_out)) 10198c2ecf20Sopenharmony_ci return PTR_ERR(cmd_out); 10208c2ecf20Sopenharmony_ci 10218c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 10228c2ecf20Sopenharmony_ci err = mlx5_cmd_exec(dev->mdev, cmd_in, 10238c2ecf20Sopenharmony_ci uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN), 10248c2ecf20Sopenharmony_ci cmd_out, cmd_out_len); 10258c2ecf20Sopenharmony_ci if (err) 10268c2ecf20Sopenharmony_ci return err; 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_ci return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out, 10298c2ecf20Sopenharmony_ci cmd_out_len); 10308c2ecf20Sopenharmony_ci} 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_cistatic void devx_obj_build_destroy_cmd(void *in, void *out, void *din, 10338c2ecf20Sopenharmony_ci u32 *dinlen, 10348c2ecf20Sopenharmony_ci u32 *obj_id) 10358c2ecf20Sopenharmony_ci{ 10368c2ecf20Sopenharmony_ci u16 obj_type = MLX5_GET(general_obj_in_cmd_hdr, in, obj_type); 10378c2ecf20Sopenharmony_ci u16 uid = MLX5_GET(general_obj_in_cmd_hdr, in, uid); 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 10408c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr); 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, obj_id, *obj_id); 10438c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, uid, uid); 10448c2ecf20Sopenharmony_ci 10458c2ecf20Sopenharmony_ci switch (MLX5_GET(general_obj_in_cmd_hdr, in, opcode)) { 10468c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: 10478c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 10488c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, obj_type, obj_type); 10498c2ecf20Sopenharmony_ci break; 10508c2ecf20Sopenharmony_ci 10518c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_UMEM: 10528c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 10538c2ecf20Sopenharmony_ci MLX5_CMD_OP_DESTROY_UMEM); 10548c2ecf20Sopenharmony_ci break; 10558c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_MKEY: 10568c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_MKEY); 10578c2ecf20Sopenharmony_ci break; 10588c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_CQ: 10598c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_CQ); 10608c2ecf20Sopenharmony_ci break; 10618c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_PD: 10628c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_PD); 10638c2ecf20Sopenharmony_ci break; 10648c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN: 10658c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 10668c2ecf20Sopenharmony_ci MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN); 10678c2ecf20Sopenharmony_ci break; 10688c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RMP: 10698c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RMP); 10708c2ecf20Sopenharmony_ci break; 10718c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SQ: 10728c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SQ); 10738c2ecf20Sopenharmony_ci break; 10748c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQ: 10758c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQ); 10768c2ecf20Sopenharmony_ci break; 10778c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_RQT: 10788c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT); 10798c2ecf20Sopenharmony_ci break; 10808c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_TIR: 10818c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(create_tir_out, out, tirn); 10828c2ecf20Sopenharmony_ci MLX5_SET(destroy_tir_in, din, opcode, MLX5_CMD_OP_DESTROY_TIR); 10838c2ecf20Sopenharmony_ci MLX5_SET(destroy_tir_in, din, tirn, *obj_id); 10848c2ecf20Sopenharmony_ci break; 10858c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_TIS: 10868c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS); 10878c2ecf20Sopenharmony_ci break; 10888c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_Q_COUNTER: 10898c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 10908c2ecf20Sopenharmony_ci MLX5_CMD_OP_DEALLOC_Q_COUNTER); 10918c2ecf20Sopenharmony_ci break; 10928c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_FLOW_TABLE: 10938c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_table_in); 10948c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(create_flow_table_out, out, table_id); 10958c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_table_in, din, other_vport, 10968c2ecf20Sopenharmony_ci MLX5_GET(create_flow_table_in, in, other_vport)); 10978c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_table_in, din, vport_number, 10988c2ecf20Sopenharmony_ci MLX5_GET(create_flow_table_in, in, vport_number)); 10998c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_table_in, din, table_type, 11008c2ecf20Sopenharmony_ci MLX5_GET(create_flow_table_in, in, table_type)); 11018c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_table_in, din, table_id, *obj_id); 11028c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11038c2ecf20Sopenharmony_ci MLX5_CMD_OP_DESTROY_FLOW_TABLE); 11048c2ecf20Sopenharmony_ci break; 11058c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_FLOW_GROUP: 11068c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(destroy_flow_group_in); 11078c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(create_flow_group_out, out, group_id); 11088c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_group_in, din, other_vport, 11098c2ecf20Sopenharmony_ci MLX5_GET(create_flow_group_in, in, other_vport)); 11108c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_group_in, din, vport_number, 11118c2ecf20Sopenharmony_ci MLX5_GET(create_flow_group_in, in, vport_number)); 11128c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_group_in, din, table_type, 11138c2ecf20Sopenharmony_ci MLX5_GET(create_flow_group_in, in, table_type)); 11148c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_group_in, din, table_id, 11158c2ecf20Sopenharmony_ci MLX5_GET(create_flow_group_in, in, table_id)); 11168c2ecf20Sopenharmony_ci MLX5_SET(destroy_flow_group_in, din, group_id, *obj_id); 11178c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11188c2ecf20Sopenharmony_ci MLX5_CMD_OP_DESTROY_FLOW_GROUP); 11198c2ecf20Sopenharmony_ci break; 11208c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY: 11218c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(delete_fte_in); 11228c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(set_fte_in, in, flow_index); 11238c2ecf20Sopenharmony_ci MLX5_SET(delete_fte_in, din, other_vport, 11248c2ecf20Sopenharmony_ci MLX5_GET(set_fte_in, in, other_vport)); 11258c2ecf20Sopenharmony_ci MLX5_SET(delete_fte_in, din, vport_number, 11268c2ecf20Sopenharmony_ci MLX5_GET(set_fte_in, in, vport_number)); 11278c2ecf20Sopenharmony_ci MLX5_SET(delete_fte_in, din, table_type, 11288c2ecf20Sopenharmony_ci MLX5_GET(set_fte_in, in, table_type)); 11298c2ecf20Sopenharmony_ci MLX5_SET(delete_fte_in, din, table_id, 11308c2ecf20Sopenharmony_ci MLX5_GET(set_fte_in, in, table_id)); 11318c2ecf20Sopenharmony_ci MLX5_SET(delete_fte_in, din, flow_index, *obj_id); 11328c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11338c2ecf20Sopenharmony_ci MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); 11348c2ecf20Sopenharmony_ci break; 11358c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_FLOW_COUNTER: 11368c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11378c2ecf20Sopenharmony_ci MLX5_CMD_OP_DEALLOC_FLOW_COUNTER); 11388c2ecf20Sopenharmony_ci break; 11398c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT: 11408c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11418c2ecf20Sopenharmony_ci MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT); 11428c2ecf20Sopenharmony_ci break; 11438c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT: 11448c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11458c2ecf20Sopenharmony_ci MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT); 11468c2ecf20Sopenharmony_ci break; 11478c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT: 11488c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(destroy_scheduling_element_in); 11498c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(create_scheduling_element_out, out, 11508c2ecf20Sopenharmony_ci scheduling_element_id); 11518c2ecf20Sopenharmony_ci MLX5_SET(destroy_scheduling_element_in, din, 11528c2ecf20Sopenharmony_ci scheduling_hierarchy, 11538c2ecf20Sopenharmony_ci MLX5_GET(create_scheduling_element_in, in, 11548c2ecf20Sopenharmony_ci scheduling_hierarchy)); 11558c2ecf20Sopenharmony_ci MLX5_SET(destroy_scheduling_element_in, din, 11568c2ecf20Sopenharmony_ci scheduling_element_id, *obj_id); 11578c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11588c2ecf20Sopenharmony_ci MLX5_CMD_OP_DESTROY_SCHEDULING_ELEMENT); 11598c2ecf20Sopenharmony_ci break; 11608c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT: 11618c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(delete_vxlan_udp_dport_in); 11628c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(add_vxlan_udp_dport_in, in, vxlan_udp_port); 11638c2ecf20Sopenharmony_ci MLX5_SET(delete_vxlan_udp_dport_in, din, vxlan_udp_port, *obj_id); 11648c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11658c2ecf20Sopenharmony_ci MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT); 11668c2ecf20Sopenharmony_ci break; 11678c2ecf20Sopenharmony_ci case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: 11688c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(delete_l2_table_entry_in); 11698c2ecf20Sopenharmony_ci *obj_id = MLX5_GET(set_l2_table_entry_in, in, table_index); 11708c2ecf20Sopenharmony_ci MLX5_SET(delete_l2_table_entry_in, din, table_index, *obj_id); 11718c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11728c2ecf20Sopenharmony_ci MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY); 11738c2ecf20Sopenharmony_ci break; 11748c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_QP: 11758c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_QP); 11768c2ecf20Sopenharmony_ci break; 11778c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_SRQ: 11788c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_SRQ); 11798c2ecf20Sopenharmony_ci break; 11808c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRC_SRQ: 11818c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 11828c2ecf20Sopenharmony_ci MLX5_CMD_OP_DESTROY_XRC_SRQ); 11838c2ecf20Sopenharmony_ci break; 11848c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_DCT: 11858c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_DCT); 11868c2ecf20Sopenharmony_ci break; 11878c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_XRQ: 11888c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_XRQ); 11898c2ecf20Sopenharmony_ci break; 11908c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ATTACH_TO_MCG: 11918c2ecf20Sopenharmony_ci *dinlen = MLX5_ST_SZ_BYTES(detach_from_mcg_in); 11928c2ecf20Sopenharmony_ci MLX5_SET(detach_from_mcg_in, din, qpn, 11938c2ecf20Sopenharmony_ci MLX5_GET(attach_to_mcg_in, in, qpn)); 11948c2ecf20Sopenharmony_ci memcpy(MLX5_ADDR_OF(detach_from_mcg_in, din, multicast_gid), 11958c2ecf20Sopenharmony_ci MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid), 11968c2ecf20Sopenharmony_ci MLX5_FLD_SZ_BYTES(attach_to_mcg_in, multicast_gid)); 11978c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DETACH_FROM_MCG); 11988c2ecf20Sopenharmony_ci break; 11998c2ecf20Sopenharmony_ci case MLX5_CMD_OP_ALLOC_XRCD: 12008c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD); 12018c2ecf20Sopenharmony_ci break; 12028c2ecf20Sopenharmony_ci case MLX5_CMD_OP_CREATE_PSV: 12038c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, din, opcode, 12048c2ecf20Sopenharmony_ci MLX5_CMD_OP_DESTROY_PSV); 12058c2ecf20Sopenharmony_ci MLX5_SET(destroy_psv_in, din, psvn, 12068c2ecf20Sopenharmony_ci MLX5_GET(create_psv_out, out, psv0_index)); 12078c2ecf20Sopenharmony_ci break; 12088c2ecf20Sopenharmony_ci default: 12098c2ecf20Sopenharmony_ci /* The entry must match to one of the devx_is_obj_create_cmd */ 12108c2ecf20Sopenharmony_ci WARN_ON(true); 12118c2ecf20Sopenharmony_ci break; 12128c2ecf20Sopenharmony_ci } 12138c2ecf20Sopenharmony_ci} 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_cistatic int devx_handle_mkey_indirect(struct devx_obj *obj, 12168c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev, 12178c2ecf20Sopenharmony_ci void *in, void *out) 12188c2ecf20Sopenharmony_ci{ 12198c2ecf20Sopenharmony_ci struct mlx5_ib_devx_mr *devx_mr = &obj->devx_mr; 12208c2ecf20Sopenharmony_ci struct mlx5_core_mkey *mkey; 12218c2ecf20Sopenharmony_ci void *mkc; 12228c2ecf20Sopenharmony_ci u8 key; 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci mkey = &devx_mr->mmkey; 12258c2ecf20Sopenharmony_ci mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); 12268c2ecf20Sopenharmony_ci key = MLX5_GET(mkc, mkc, mkey_7_0); 12278c2ecf20Sopenharmony_ci mkey->key = mlx5_idx_to_mkey( 12288c2ecf20Sopenharmony_ci MLX5_GET(create_mkey_out, out, mkey_index)) | key; 12298c2ecf20Sopenharmony_ci mkey->type = MLX5_MKEY_INDIRECT_DEVX; 12308c2ecf20Sopenharmony_ci mkey->iova = MLX5_GET64(mkc, mkc, start_addr); 12318c2ecf20Sopenharmony_ci mkey->size = MLX5_GET64(mkc, mkc, len); 12328c2ecf20Sopenharmony_ci mkey->pd = MLX5_GET(mkc, mkc, pd); 12338c2ecf20Sopenharmony_ci devx_mr->ndescs = MLX5_GET(mkc, mkc, translations_octword_size); 12348c2ecf20Sopenharmony_ci 12358c2ecf20Sopenharmony_ci return xa_err(xa_store(&dev->odp_mkeys, mlx5_base_mkey(mkey->key), mkey, 12368c2ecf20Sopenharmony_ci GFP_KERNEL)); 12378c2ecf20Sopenharmony_ci} 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_cistatic int devx_handle_mkey_create(struct mlx5_ib_dev *dev, 12408c2ecf20Sopenharmony_ci struct devx_obj *obj, 12418c2ecf20Sopenharmony_ci void *in, int in_len) 12428c2ecf20Sopenharmony_ci{ 12438c2ecf20Sopenharmony_ci int min_len = MLX5_BYTE_OFF(create_mkey_in, memory_key_mkey_entry) + 12448c2ecf20Sopenharmony_ci MLX5_FLD_SZ_BYTES(create_mkey_in, 12458c2ecf20Sopenharmony_ci memory_key_mkey_entry); 12468c2ecf20Sopenharmony_ci void *mkc; 12478c2ecf20Sopenharmony_ci u8 access_mode; 12488c2ecf20Sopenharmony_ci 12498c2ecf20Sopenharmony_ci if (in_len < min_len) 12508c2ecf20Sopenharmony_ci return -EINVAL; 12518c2ecf20Sopenharmony_ci 12528c2ecf20Sopenharmony_ci mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); 12538c2ecf20Sopenharmony_ci 12548c2ecf20Sopenharmony_ci access_mode = MLX5_GET(mkc, mkc, access_mode_1_0); 12558c2ecf20Sopenharmony_ci access_mode |= MLX5_GET(mkc, mkc, access_mode_4_2) << 2; 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_ci if (access_mode == MLX5_MKC_ACCESS_MODE_KLMS || 12588c2ecf20Sopenharmony_ci access_mode == MLX5_MKC_ACCESS_MODE_KSM) { 12598c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) 12608c2ecf20Sopenharmony_ci obj->flags |= DEVX_OBJ_FLAGS_INDIRECT_MKEY; 12618c2ecf20Sopenharmony_ci return 0; 12628c2ecf20Sopenharmony_ci } 12638c2ecf20Sopenharmony_ci 12648c2ecf20Sopenharmony_ci MLX5_SET(create_mkey_in, in, mkey_umem_valid, 1); 12658c2ecf20Sopenharmony_ci return 0; 12668c2ecf20Sopenharmony_ci} 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_cistatic void devx_cleanup_subscription(struct mlx5_ib_dev *dev, 12698c2ecf20Sopenharmony_ci struct devx_event_subscription *sub) 12708c2ecf20Sopenharmony_ci{ 12718c2ecf20Sopenharmony_ci struct devx_event *event; 12728c2ecf20Sopenharmony_ci struct devx_obj_event *xa_val_level2; 12738c2ecf20Sopenharmony_ci 12748c2ecf20Sopenharmony_ci if (sub->is_cleaned) 12758c2ecf20Sopenharmony_ci return; 12768c2ecf20Sopenharmony_ci 12778c2ecf20Sopenharmony_ci sub->is_cleaned = 1; 12788c2ecf20Sopenharmony_ci list_del_rcu(&sub->xa_list); 12798c2ecf20Sopenharmony_ci 12808c2ecf20Sopenharmony_ci if (list_empty(&sub->obj_list)) 12818c2ecf20Sopenharmony_ci return; 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_ci list_del_rcu(&sub->obj_list); 12848c2ecf20Sopenharmony_ci /* check whether key level 1 for this obj_sub_list is empty */ 12858c2ecf20Sopenharmony_ci event = xa_load(&dev->devx_event_table.event_xa, 12868c2ecf20Sopenharmony_ci sub->xa_key_level1); 12878c2ecf20Sopenharmony_ci WARN_ON(!event); 12888c2ecf20Sopenharmony_ci 12898c2ecf20Sopenharmony_ci xa_val_level2 = xa_load(&event->object_ids, sub->xa_key_level2); 12908c2ecf20Sopenharmony_ci if (list_empty(&xa_val_level2->obj_sub_list)) { 12918c2ecf20Sopenharmony_ci xa_erase(&event->object_ids, 12928c2ecf20Sopenharmony_ci sub->xa_key_level2); 12938c2ecf20Sopenharmony_ci kfree_rcu(xa_val_level2, rcu); 12948c2ecf20Sopenharmony_ci } 12958c2ecf20Sopenharmony_ci} 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_cistatic int devx_obj_cleanup(struct ib_uobject *uobject, 12988c2ecf20Sopenharmony_ci enum rdma_remove_reason why, 12998c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 13008c2ecf20Sopenharmony_ci{ 13018c2ecf20Sopenharmony_ci u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 13028c2ecf20Sopenharmony_ci struct mlx5_devx_event_table *devx_event_table; 13038c2ecf20Sopenharmony_ci struct devx_obj *obj = uobject->object; 13048c2ecf20Sopenharmony_ci struct devx_event_subscription *sub_entry, *tmp; 13058c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev; 13068c2ecf20Sopenharmony_ci int ret; 13078c2ecf20Sopenharmony_ci 13088c2ecf20Sopenharmony_ci dev = mlx5_udata_to_mdev(&attrs->driver_udata); 13098c2ecf20Sopenharmony_ci if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { 13108c2ecf20Sopenharmony_ci /* 13118c2ecf20Sopenharmony_ci * The pagefault_single_data_segment() does commands against 13128c2ecf20Sopenharmony_ci * the mmkey, we must wait for that to stop before freeing the 13138c2ecf20Sopenharmony_ci * mkey, as another allocation could get the same mkey #. 13148c2ecf20Sopenharmony_ci */ 13158c2ecf20Sopenharmony_ci xa_erase(&obj->ib_dev->odp_mkeys, 13168c2ecf20Sopenharmony_ci mlx5_base_mkey(obj->devx_mr.mmkey.key)); 13178c2ecf20Sopenharmony_ci synchronize_srcu(&dev->odp_srcu); 13188c2ecf20Sopenharmony_ci } 13198c2ecf20Sopenharmony_ci 13208c2ecf20Sopenharmony_ci if (obj->flags & DEVX_OBJ_FLAGS_DCT) 13218c2ecf20Sopenharmony_ci ret = mlx5_core_destroy_dct(obj->ib_dev, &obj->core_dct); 13228c2ecf20Sopenharmony_ci else if (obj->flags & DEVX_OBJ_FLAGS_CQ) 13238c2ecf20Sopenharmony_ci ret = mlx5_core_destroy_cq(obj->ib_dev->mdev, &obj->core_cq); 13248c2ecf20Sopenharmony_ci else 13258c2ecf20Sopenharmony_ci ret = mlx5_cmd_exec(obj->ib_dev->mdev, obj->dinbox, 13268c2ecf20Sopenharmony_ci obj->dinlen, out, sizeof(out)); 13278c2ecf20Sopenharmony_ci if (ib_is_destroy_retryable(ret, why, uobject)) 13288c2ecf20Sopenharmony_ci return ret; 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_ci devx_event_table = &dev->devx_event_table; 13318c2ecf20Sopenharmony_ci 13328c2ecf20Sopenharmony_ci mutex_lock(&devx_event_table->event_xa_lock); 13338c2ecf20Sopenharmony_ci list_for_each_entry_safe(sub_entry, tmp, &obj->event_sub, obj_list) 13348c2ecf20Sopenharmony_ci devx_cleanup_subscription(dev, sub_entry); 13358c2ecf20Sopenharmony_ci mutex_unlock(&devx_event_table->event_xa_lock); 13368c2ecf20Sopenharmony_ci 13378c2ecf20Sopenharmony_ci kfree(obj); 13388c2ecf20Sopenharmony_ci return ret; 13398c2ecf20Sopenharmony_ci} 13408c2ecf20Sopenharmony_ci 13418c2ecf20Sopenharmony_cistatic void devx_cq_comp(struct mlx5_core_cq *mcq, struct mlx5_eqe *eqe) 13428c2ecf20Sopenharmony_ci{ 13438c2ecf20Sopenharmony_ci struct devx_obj *obj = container_of(mcq, struct devx_obj, core_cq); 13448c2ecf20Sopenharmony_ci struct mlx5_devx_event_table *table; 13458c2ecf20Sopenharmony_ci struct devx_event *event; 13468c2ecf20Sopenharmony_ci struct devx_obj_event *obj_event; 13478c2ecf20Sopenharmony_ci u32 obj_id = mcq->cqn; 13488c2ecf20Sopenharmony_ci 13498c2ecf20Sopenharmony_ci table = &obj->ib_dev->devx_event_table; 13508c2ecf20Sopenharmony_ci rcu_read_lock(); 13518c2ecf20Sopenharmony_ci event = xa_load(&table->event_xa, MLX5_EVENT_TYPE_COMP); 13528c2ecf20Sopenharmony_ci if (!event) 13538c2ecf20Sopenharmony_ci goto out; 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci obj_event = xa_load(&event->object_ids, obj_id); 13568c2ecf20Sopenharmony_ci if (!obj_event) 13578c2ecf20Sopenharmony_ci goto out; 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci dispatch_event_fd(&obj_event->obj_sub_list, eqe); 13608c2ecf20Sopenharmony_ciout: 13618c2ecf20Sopenharmony_ci rcu_read_unlock(); 13628c2ecf20Sopenharmony_ci} 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)( 13658c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 13668c2ecf20Sopenharmony_ci{ 13678c2ecf20Sopenharmony_ci void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN); 13688c2ecf20Sopenharmony_ci int cmd_out_len = uverbs_attr_get_len(attrs, 13698c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT); 13708c2ecf20Sopenharmony_ci int cmd_in_len = uverbs_attr_get_len(attrs, 13718c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN); 13728c2ecf20Sopenharmony_ci void *cmd_out; 13738c2ecf20Sopenharmony_ci struct ib_uobject *uobj = uverbs_attr_get_uobject( 13748c2ecf20Sopenharmony_ci attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE); 13758c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 13768c2ecf20Sopenharmony_ci &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 13778c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 13788c2ecf20Sopenharmony_ci u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 13798c2ecf20Sopenharmony_ci struct devx_obj *obj; 13808c2ecf20Sopenharmony_ci u16 obj_type = 0; 13818c2ecf20Sopenharmony_ci int err; 13828c2ecf20Sopenharmony_ci int uid; 13838c2ecf20Sopenharmony_ci u32 obj_id; 13848c2ecf20Sopenharmony_ci u16 opcode; 13858c2ecf20Sopenharmony_ci 13868c2ecf20Sopenharmony_ci if (MLX5_GET(general_obj_in_cmd_hdr, cmd_in, vhca_tunnel_id)) 13878c2ecf20Sopenharmony_ci return -EINVAL; 13888c2ecf20Sopenharmony_ci 13898c2ecf20Sopenharmony_ci uid = devx_get_uid(c, cmd_in); 13908c2ecf20Sopenharmony_ci if (uid < 0) 13918c2ecf20Sopenharmony_ci return uid; 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ci if (!devx_is_obj_create_cmd(cmd_in, &opcode)) 13948c2ecf20Sopenharmony_ci return -EINVAL; 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci cmd_out = uverbs_zalloc(attrs, cmd_out_len); 13978c2ecf20Sopenharmony_ci if (IS_ERR(cmd_out)) 13988c2ecf20Sopenharmony_ci return PTR_ERR(cmd_out); 13998c2ecf20Sopenharmony_ci 14008c2ecf20Sopenharmony_ci obj = kzalloc(sizeof(struct devx_obj), GFP_KERNEL); 14018c2ecf20Sopenharmony_ci if (!obj) 14028c2ecf20Sopenharmony_ci return -ENOMEM; 14038c2ecf20Sopenharmony_ci 14048c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 14058c2ecf20Sopenharmony_ci if (opcode == MLX5_CMD_OP_CREATE_MKEY) { 14068c2ecf20Sopenharmony_ci err = devx_handle_mkey_create(dev, obj, cmd_in, cmd_in_len); 14078c2ecf20Sopenharmony_ci if (err) 14088c2ecf20Sopenharmony_ci goto obj_free; 14098c2ecf20Sopenharmony_ci } else { 14108c2ecf20Sopenharmony_ci devx_set_umem_valid(cmd_in); 14118c2ecf20Sopenharmony_ci } 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_ci if (opcode == MLX5_CMD_OP_CREATE_DCT) { 14148c2ecf20Sopenharmony_ci obj->flags |= DEVX_OBJ_FLAGS_DCT; 14158c2ecf20Sopenharmony_ci err = mlx5_core_create_dct(dev, &obj->core_dct, cmd_in, 14168c2ecf20Sopenharmony_ci cmd_in_len, cmd_out, cmd_out_len); 14178c2ecf20Sopenharmony_ci } else if (opcode == MLX5_CMD_OP_CREATE_CQ) { 14188c2ecf20Sopenharmony_ci obj->flags |= DEVX_OBJ_FLAGS_CQ; 14198c2ecf20Sopenharmony_ci obj->core_cq.comp = devx_cq_comp; 14208c2ecf20Sopenharmony_ci err = mlx5_core_create_cq(dev->mdev, &obj->core_cq, 14218c2ecf20Sopenharmony_ci cmd_in, cmd_in_len, cmd_out, 14228c2ecf20Sopenharmony_ci cmd_out_len); 14238c2ecf20Sopenharmony_ci } else { 14248c2ecf20Sopenharmony_ci err = mlx5_cmd_exec(dev->mdev, cmd_in, 14258c2ecf20Sopenharmony_ci cmd_in_len, 14268c2ecf20Sopenharmony_ci cmd_out, cmd_out_len); 14278c2ecf20Sopenharmony_ci } 14288c2ecf20Sopenharmony_ci 14298c2ecf20Sopenharmony_ci if (err) 14308c2ecf20Sopenharmony_ci goto obj_free; 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci if (opcode == MLX5_CMD_OP_ALLOC_FLOW_COUNTER) { 14338c2ecf20Sopenharmony_ci u32 bulk = MLX5_GET(alloc_flow_counter_in, 14348c2ecf20Sopenharmony_ci cmd_in, 14358c2ecf20Sopenharmony_ci flow_counter_bulk_log_size); 14368c2ecf20Sopenharmony_ci 14378c2ecf20Sopenharmony_ci if (bulk) 14388c2ecf20Sopenharmony_ci bulk = 1 << bulk; 14398c2ecf20Sopenharmony_ci else 14408c2ecf20Sopenharmony_ci bulk = 128UL * MLX5_GET(alloc_flow_counter_in, 14418c2ecf20Sopenharmony_ci cmd_in, 14428c2ecf20Sopenharmony_ci flow_counter_bulk); 14438c2ecf20Sopenharmony_ci obj->flow_counter_bulk_size = bulk; 14448c2ecf20Sopenharmony_ci } 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci uobj->object = obj; 14478c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&obj->event_sub); 14488c2ecf20Sopenharmony_ci obj->ib_dev = dev; 14498c2ecf20Sopenharmony_ci devx_obj_build_destroy_cmd(cmd_in, cmd_out, obj->dinbox, &obj->dinlen, 14508c2ecf20Sopenharmony_ci &obj_id); 14518c2ecf20Sopenharmony_ci WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32)); 14528c2ecf20Sopenharmony_ci 14538c2ecf20Sopenharmony_ci err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len); 14548c2ecf20Sopenharmony_ci if (err) 14558c2ecf20Sopenharmony_ci goto obj_destroy; 14568c2ecf20Sopenharmony_ci 14578c2ecf20Sopenharmony_ci if (opcode == MLX5_CMD_OP_CREATE_GENERAL_OBJECT) 14588c2ecf20Sopenharmony_ci obj_type = MLX5_GET(general_obj_in_cmd_hdr, cmd_in, obj_type); 14598c2ecf20Sopenharmony_ci obj->obj_id = get_enc_obj_id(opcode | obj_type << 16, obj_id); 14608c2ecf20Sopenharmony_ci 14618c2ecf20Sopenharmony_ci if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { 14628c2ecf20Sopenharmony_ci err = devx_handle_mkey_indirect(obj, dev, cmd_in, cmd_out); 14638c2ecf20Sopenharmony_ci if (err) 14648c2ecf20Sopenharmony_ci goto obj_destroy; 14658c2ecf20Sopenharmony_ci } 14668c2ecf20Sopenharmony_ci return 0; 14678c2ecf20Sopenharmony_ci 14688c2ecf20Sopenharmony_ciobj_destroy: 14698c2ecf20Sopenharmony_ci if (obj->flags & DEVX_OBJ_FLAGS_DCT) 14708c2ecf20Sopenharmony_ci mlx5_core_destroy_dct(obj->ib_dev, &obj->core_dct); 14718c2ecf20Sopenharmony_ci else if (obj->flags & DEVX_OBJ_FLAGS_CQ) 14728c2ecf20Sopenharmony_ci mlx5_core_destroy_cq(obj->ib_dev->mdev, &obj->core_cq); 14738c2ecf20Sopenharmony_ci else 14748c2ecf20Sopenharmony_ci mlx5_cmd_exec(obj->ib_dev->mdev, obj->dinbox, obj->dinlen, out, 14758c2ecf20Sopenharmony_ci sizeof(out)); 14768c2ecf20Sopenharmony_ciobj_free: 14778c2ecf20Sopenharmony_ci kfree(obj); 14788c2ecf20Sopenharmony_ci return err; 14798c2ecf20Sopenharmony_ci} 14808c2ecf20Sopenharmony_ci 14818c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MODIFY)( 14828c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 14838c2ecf20Sopenharmony_ci{ 14848c2ecf20Sopenharmony_ci void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN); 14858c2ecf20Sopenharmony_ci int cmd_out_len = uverbs_attr_get_len(attrs, 14868c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT); 14878c2ecf20Sopenharmony_ci struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 14888c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE); 14898c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 14908c2ecf20Sopenharmony_ci &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 14918c2ecf20Sopenharmony_ci struct mlx5_ib_dev *mdev = to_mdev(c->ibucontext.device); 14928c2ecf20Sopenharmony_ci void *cmd_out; 14938c2ecf20Sopenharmony_ci int err; 14948c2ecf20Sopenharmony_ci int uid; 14958c2ecf20Sopenharmony_ci 14968c2ecf20Sopenharmony_ci if (MLX5_GET(general_obj_in_cmd_hdr, cmd_in, vhca_tunnel_id)) 14978c2ecf20Sopenharmony_ci return -EINVAL; 14988c2ecf20Sopenharmony_ci 14998c2ecf20Sopenharmony_ci uid = devx_get_uid(c, cmd_in); 15008c2ecf20Sopenharmony_ci if (uid < 0) 15018c2ecf20Sopenharmony_ci return uid; 15028c2ecf20Sopenharmony_ci 15038c2ecf20Sopenharmony_ci if (!devx_is_obj_modify_cmd(cmd_in)) 15048c2ecf20Sopenharmony_ci return -EINVAL; 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci if (!devx_is_valid_obj_id(attrs, uobj, cmd_in)) 15078c2ecf20Sopenharmony_ci return -EINVAL; 15088c2ecf20Sopenharmony_ci 15098c2ecf20Sopenharmony_ci cmd_out = uverbs_zalloc(attrs, cmd_out_len); 15108c2ecf20Sopenharmony_ci if (IS_ERR(cmd_out)) 15118c2ecf20Sopenharmony_ci return PTR_ERR(cmd_out); 15128c2ecf20Sopenharmony_ci 15138c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 15148c2ecf20Sopenharmony_ci devx_set_umem_valid(cmd_in); 15158c2ecf20Sopenharmony_ci 15168c2ecf20Sopenharmony_ci err = mlx5_cmd_exec(mdev->mdev, cmd_in, 15178c2ecf20Sopenharmony_ci uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN), 15188c2ecf20Sopenharmony_ci cmd_out, cmd_out_len); 15198c2ecf20Sopenharmony_ci if (err) 15208c2ecf20Sopenharmony_ci return err; 15218c2ecf20Sopenharmony_ci 15228c2ecf20Sopenharmony_ci return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 15238c2ecf20Sopenharmony_ci cmd_out, cmd_out_len); 15248c2ecf20Sopenharmony_ci} 15258c2ecf20Sopenharmony_ci 15268c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)( 15278c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 15288c2ecf20Sopenharmony_ci{ 15298c2ecf20Sopenharmony_ci void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN); 15308c2ecf20Sopenharmony_ci int cmd_out_len = uverbs_attr_get_len(attrs, 15318c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT); 15328c2ecf20Sopenharmony_ci struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, 15338c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE); 15348c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 15358c2ecf20Sopenharmony_ci &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 15368c2ecf20Sopenharmony_ci void *cmd_out; 15378c2ecf20Sopenharmony_ci int err; 15388c2ecf20Sopenharmony_ci int uid; 15398c2ecf20Sopenharmony_ci struct mlx5_ib_dev *mdev = to_mdev(c->ibucontext.device); 15408c2ecf20Sopenharmony_ci 15418c2ecf20Sopenharmony_ci if (MLX5_GET(general_obj_in_cmd_hdr, cmd_in, vhca_tunnel_id)) 15428c2ecf20Sopenharmony_ci return -EINVAL; 15438c2ecf20Sopenharmony_ci 15448c2ecf20Sopenharmony_ci uid = devx_get_uid(c, cmd_in); 15458c2ecf20Sopenharmony_ci if (uid < 0) 15468c2ecf20Sopenharmony_ci return uid; 15478c2ecf20Sopenharmony_ci 15488c2ecf20Sopenharmony_ci if (!devx_is_obj_query_cmd(cmd_in)) 15498c2ecf20Sopenharmony_ci return -EINVAL; 15508c2ecf20Sopenharmony_ci 15518c2ecf20Sopenharmony_ci if (!devx_is_valid_obj_id(attrs, uobj, cmd_in)) 15528c2ecf20Sopenharmony_ci return -EINVAL; 15538c2ecf20Sopenharmony_ci 15548c2ecf20Sopenharmony_ci cmd_out = uverbs_zalloc(attrs, cmd_out_len); 15558c2ecf20Sopenharmony_ci if (IS_ERR(cmd_out)) 15568c2ecf20Sopenharmony_ci return PTR_ERR(cmd_out); 15578c2ecf20Sopenharmony_ci 15588c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 15598c2ecf20Sopenharmony_ci err = mlx5_cmd_exec(mdev->mdev, cmd_in, 15608c2ecf20Sopenharmony_ci uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN), 15618c2ecf20Sopenharmony_ci cmd_out, cmd_out_len); 15628c2ecf20Sopenharmony_ci if (err) 15638c2ecf20Sopenharmony_ci return err; 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_ci return uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, 15668c2ecf20Sopenharmony_ci cmd_out, cmd_out_len); 15678c2ecf20Sopenharmony_ci} 15688c2ecf20Sopenharmony_ci 15698c2ecf20Sopenharmony_cistruct devx_async_event_queue { 15708c2ecf20Sopenharmony_ci spinlock_t lock; 15718c2ecf20Sopenharmony_ci wait_queue_head_t poll_wait; 15728c2ecf20Sopenharmony_ci struct list_head event_list; 15738c2ecf20Sopenharmony_ci atomic_t bytes_in_use; 15748c2ecf20Sopenharmony_ci u8 is_destroyed:1; 15758c2ecf20Sopenharmony_ci}; 15768c2ecf20Sopenharmony_ci 15778c2ecf20Sopenharmony_cistruct devx_async_cmd_event_file { 15788c2ecf20Sopenharmony_ci struct ib_uobject uobj; 15798c2ecf20Sopenharmony_ci struct devx_async_event_queue ev_queue; 15808c2ecf20Sopenharmony_ci struct mlx5_async_ctx async_ctx; 15818c2ecf20Sopenharmony_ci}; 15828c2ecf20Sopenharmony_ci 15838c2ecf20Sopenharmony_cistatic void devx_init_event_queue(struct devx_async_event_queue *ev_queue) 15848c2ecf20Sopenharmony_ci{ 15858c2ecf20Sopenharmony_ci spin_lock_init(&ev_queue->lock); 15868c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&ev_queue->event_list); 15878c2ecf20Sopenharmony_ci init_waitqueue_head(&ev_queue->poll_wait); 15888c2ecf20Sopenharmony_ci atomic_set(&ev_queue->bytes_in_use, 0); 15898c2ecf20Sopenharmony_ci ev_queue->is_destroyed = 0; 15908c2ecf20Sopenharmony_ci} 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC)( 15938c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 15948c2ecf20Sopenharmony_ci{ 15958c2ecf20Sopenharmony_ci struct devx_async_cmd_event_file *ev_file; 15968c2ecf20Sopenharmony_ci 15978c2ecf20Sopenharmony_ci struct ib_uobject *uobj = uverbs_attr_get_uobject( 15988c2ecf20Sopenharmony_ci attrs, MLX5_IB_ATTR_DEVX_ASYNC_CMD_FD_ALLOC_HANDLE); 15998c2ecf20Sopenharmony_ci struct mlx5_ib_dev *mdev = mlx5_udata_to_mdev(&attrs->driver_udata); 16008c2ecf20Sopenharmony_ci 16018c2ecf20Sopenharmony_ci ev_file = container_of(uobj, struct devx_async_cmd_event_file, 16028c2ecf20Sopenharmony_ci uobj); 16038c2ecf20Sopenharmony_ci devx_init_event_queue(&ev_file->ev_queue); 16048c2ecf20Sopenharmony_ci mlx5_cmd_init_async_ctx(mdev->mdev, &ev_file->async_ctx); 16058c2ecf20Sopenharmony_ci return 0; 16068c2ecf20Sopenharmony_ci} 16078c2ecf20Sopenharmony_ci 16088c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_ASYNC_EVENT_FD_ALLOC)( 16098c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 16108c2ecf20Sopenharmony_ci{ 16118c2ecf20Sopenharmony_ci struct ib_uobject *uobj = uverbs_attr_get_uobject( 16128c2ecf20Sopenharmony_ci attrs, MLX5_IB_ATTR_DEVX_ASYNC_EVENT_FD_ALLOC_HANDLE); 16138c2ecf20Sopenharmony_ci struct devx_async_event_file *ev_file; 16148c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 16158c2ecf20Sopenharmony_ci &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 16168c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 16178c2ecf20Sopenharmony_ci u32 flags; 16188c2ecf20Sopenharmony_ci int err; 16198c2ecf20Sopenharmony_ci 16208c2ecf20Sopenharmony_ci err = uverbs_get_flags32(&flags, attrs, 16218c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_ASYNC_EVENT_FD_ALLOC_FLAGS, 16228c2ecf20Sopenharmony_ci MLX5_IB_UAPI_DEVX_CR_EV_CH_FLAGS_OMIT_DATA); 16238c2ecf20Sopenharmony_ci 16248c2ecf20Sopenharmony_ci if (err) 16258c2ecf20Sopenharmony_ci return err; 16268c2ecf20Sopenharmony_ci 16278c2ecf20Sopenharmony_ci ev_file = container_of(uobj, struct devx_async_event_file, 16288c2ecf20Sopenharmony_ci uobj); 16298c2ecf20Sopenharmony_ci spin_lock_init(&ev_file->lock); 16308c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&ev_file->event_list); 16318c2ecf20Sopenharmony_ci init_waitqueue_head(&ev_file->poll_wait); 16328c2ecf20Sopenharmony_ci if (flags & MLX5_IB_UAPI_DEVX_CR_EV_CH_FLAGS_OMIT_DATA) 16338c2ecf20Sopenharmony_ci ev_file->omit_data = 1; 16348c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&ev_file->subscribed_events_list); 16358c2ecf20Sopenharmony_ci ev_file->dev = dev; 16368c2ecf20Sopenharmony_ci get_device(&dev->ib_dev.dev); 16378c2ecf20Sopenharmony_ci return 0; 16388c2ecf20Sopenharmony_ci} 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_cistatic void devx_query_callback(int status, struct mlx5_async_work *context) 16418c2ecf20Sopenharmony_ci{ 16428c2ecf20Sopenharmony_ci struct devx_async_data *async_data = 16438c2ecf20Sopenharmony_ci container_of(context, struct devx_async_data, cb_work); 16448c2ecf20Sopenharmony_ci struct devx_async_cmd_event_file *ev_file = async_data->ev_file; 16458c2ecf20Sopenharmony_ci struct devx_async_event_queue *ev_queue = &ev_file->ev_queue; 16468c2ecf20Sopenharmony_ci unsigned long flags; 16478c2ecf20Sopenharmony_ci 16488c2ecf20Sopenharmony_ci /* 16498c2ecf20Sopenharmony_ci * Note that if the struct devx_async_cmd_event_file uobj begins to be 16508c2ecf20Sopenharmony_ci * destroyed it will block at mlx5_cmd_cleanup_async_ctx() until this 16518c2ecf20Sopenharmony_ci * routine returns, ensuring that it always remains valid here. 16528c2ecf20Sopenharmony_ci */ 16538c2ecf20Sopenharmony_ci spin_lock_irqsave(&ev_queue->lock, flags); 16548c2ecf20Sopenharmony_ci list_add_tail(&async_data->list, &ev_queue->event_list); 16558c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ev_queue->lock, flags); 16568c2ecf20Sopenharmony_ci 16578c2ecf20Sopenharmony_ci wake_up_interruptible(&ev_queue->poll_wait); 16588c2ecf20Sopenharmony_ci} 16598c2ecf20Sopenharmony_ci 16608c2ecf20Sopenharmony_ci#define MAX_ASYNC_BYTES_IN_USE (1024 * 1024) /* 1MB */ 16618c2ecf20Sopenharmony_ci 16628c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY)( 16638c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 16648c2ecf20Sopenharmony_ci{ 16658c2ecf20Sopenharmony_ci void *cmd_in = uverbs_attr_get_alloced_ptr(attrs, 16668c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN); 16678c2ecf20Sopenharmony_ci struct ib_uobject *uobj = uverbs_attr_get_uobject( 16688c2ecf20Sopenharmony_ci attrs, 16698c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_HANDLE); 16708c2ecf20Sopenharmony_ci u16 cmd_out_len; 16718c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 16728c2ecf20Sopenharmony_ci &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 16738c2ecf20Sopenharmony_ci struct ib_uobject *fd_uobj; 16748c2ecf20Sopenharmony_ci int err; 16758c2ecf20Sopenharmony_ci int uid; 16768c2ecf20Sopenharmony_ci struct mlx5_ib_dev *mdev = to_mdev(c->ibucontext.device); 16778c2ecf20Sopenharmony_ci struct devx_async_cmd_event_file *ev_file; 16788c2ecf20Sopenharmony_ci struct devx_async_data *async_data; 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_ci if (MLX5_GET(general_obj_in_cmd_hdr, cmd_in, vhca_tunnel_id)) 16818c2ecf20Sopenharmony_ci return -EINVAL; 16828c2ecf20Sopenharmony_ci 16838c2ecf20Sopenharmony_ci uid = devx_get_uid(c, cmd_in); 16848c2ecf20Sopenharmony_ci if (uid < 0) 16858c2ecf20Sopenharmony_ci return uid; 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci if (!devx_is_obj_query_cmd(cmd_in)) 16888c2ecf20Sopenharmony_ci return -EINVAL; 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_ci err = uverbs_get_const(&cmd_out_len, attrs, 16918c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_OUT_LEN); 16928c2ecf20Sopenharmony_ci if (err) 16938c2ecf20Sopenharmony_ci return err; 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_ci if (!devx_is_valid_obj_id(attrs, uobj, cmd_in)) 16968c2ecf20Sopenharmony_ci return -EINVAL; 16978c2ecf20Sopenharmony_ci 16988c2ecf20Sopenharmony_ci fd_uobj = uverbs_attr_get_uobject(attrs, 16998c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_FD); 17008c2ecf20Sopenharmony_ci if (IS_ERR(fd_uobj)) 17018c2ecf20Sopenharmony_ci return PTR_ERR(fd_uobj); 17028c2ecf20Sopenharmony_ci 17038c2ecf20Sopenharmony_ci ev_file = container_of(fd_uobj, struct devx_async_cmd_event_file, 17048c2ecf20Sopenharmony_ci uobj); 17058c2ecf20Sopenharmony_ci 17068c2ecf20Sopenharmony_ci if (atomic_add_return(cmd_out_len, &ev_file->ev_queue.bytes_in_use) > 17078c2ecf20Sopenharmony_ci MAX_ASYNC_BYTES_IN_USE) { 17088c2ecf20Sopenharmony_ci atomic_sub(cmd_out_len, &ev_file->ev_queue.bytes_in_use); 17098c2ecf20Sopenharmony_ci return -EAGAIN; 17108c2ecf20Sopenharmony_ci } 17118c2ecf20Sopenharmony_ci 17128c2ecf20Sopenharmony_ci async_data = kvzalloc(struct_size(async_data, hdr.out_data, 17138c2ecf20Sopenharmony_ci cmd_out_len), GFP_KERNEL); 17148c2ecf20Sopenharmony_ci if (!async_data) { 17158c2ecf20Sopenharmony_ci err = -ENOMEM; 17168c2ecf20Sopenharmony_ci goto sub_bytes; 17178c2ecf20Sopenharmony_ci } 17188c2ecf20Sopenharmony_ci 17198c2ecf20Sopenharmony_ci err = uverbs_copy_from(&async_data->hdr.wr_id, attrs, 17208c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_WR_ID); 17218c2ecf20Sopenharmony_ci if (err) 17228c2ecf20Sopenharmony_ci goto free_async; 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci async_data->cmd_out_len = cmd_out_len; 17258c2ecf20Sopenharmony_ci async_data->mdev = mdev; 17268c2ecf20Sopenharmony_ci async_data->ev_file = ev_file; 17278c2ecf20Sopenharmony_ci 17288c2ecf20Sopenharmony_ci MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); 17298c2ecf20Sopenharmony_ci err = mlx5_cmd_exec_cb(&ev_file->async_ctx, cmd_in, 17308c2ecf20Sopenharmony_ci uverbs_attr_get_len(attrs, 17318c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN), 17328c2ecf20Sopenharmony_ci async_data->hdr.out_data, 17338c2ecf20Sopenharmony_ci async_data->cmd_out_len, 17348c2ecf20Sopenharmony_ci devx_query_callback, &async_data->cb_work); 17358c2ecf20Sopenharmony_ci 17368c2ecf20Sopenharmony_ci if (err) 17378c2ecf20Sopenharmony_ci goto free_async; 17388c2ecf20Sopenharmony_ci 17398c2ecf20Sopenharmony_ci return 0; 17408c2ecf20Sopenharmony_ci 17418c2ecf20Sopenharmony_cifree_async: 17428c2ecf20Sopenharmony_ci kvfree(async_data); 17438c2ecf20Sopenharmony_cisub_bytes: 17448c2ecf20Sopenharmony_ci atomic_sub(cmd_out_len, &ev_file->ev_queue.bytes_in_use); 17458c2ecf20Sopenharmony_ci return err; 17468c2ecf20Sopenharmony_ci} 17478c2ecf20Sopenharmony_ci 17488c2ecf20Sopenharmony_cistatic void 17498c2ecf20Sopenharmony_cisubscribe_event_xa_dealloc(struct mlx5_devx_event_table *devx_event_table, 17508c2ecf20Sopenharmony_ci u32 key_level1, 17518c2ecf20Sopenharmony_ci bool is_level2, 17528c2ecf20Sopenharmony_ci u32 key_level2) 17538c2ecf20Sopenharmony_ci{ 17548c2ecf20Sopenharmony_ci struct devx_event *event; 17558c2ecf20Sopenharmony_ci struct devx_obj_event *xa_val_level2; 17568c2ecf20Sopenharmony_ci 17578c2ecf20Sopenharmony_ci /* Level 1 is valid for future use, no need to free */ 17588c2ecf20Sopenharmony_ci if (!is_level2) 17598c2ecf20Sopenharmony_ci return; 17608c2ecf20Sopenharmony_ci 17618c2ecf20Sopenharmony_ci event = xa_load(&devx_event_table->event_xa, key_level1); 17628c2ecf20Sopenharmony_ci WARN_ON(!event); 17638c2ecf20Sopenharmony_ci 17648c2ecf20Sopenharmony_ci xa_val_level2 = xa_load(&event->object_ids, 17658c2ecf20Sopenharmony_ci key_level2); 17668c2ecf20Sopenharmony_ci if (list_empty(&xa_val_level2->obj_sub_list)) { 17678c2ecf20Sopenharmony_ci xa_erase(&event->object_ids, 17688c2ecf20Sopenharmony_ci key_level2); 17698c2ecf20Sopenharmony_ci kfree_rcu(xa_val_level2, rcu); 17708c2ecf20Sopenharmony_ci } 17718c2ecf20Sopenharmony_ci} 17728c2ecf20Sopenharmony_ci 17738c2ecf20Sopenharmony_cistatic int 17748c2ecf20Sopenharmony_cisubscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table, 17758c2ecf20Sopenharmony_ci u32 key_level1, 17768c2ecf20Sopenharmony_ci bool is_level2, 17778c2ecf20Sopenharmony_ci u32 key_level2) 17788c2ecf20Sopenharmony_ci{ 17798c2ecf20Sopenharmony_ci struct devx_obj_event *obj_event; 17808c2ecf20Sopenharmony_ci struct devx_event *event; 17818c2ecf20Sopenharmony_ci int err; 17828c2ecf20Sopenharmony_ci 17838c2ecf20Sopenharmony_ci event = xa_load(&devx_event_table->event_xa, key_level1); 17848c2ecf20Sopenharmony_ci if (!event) { 17858c2ecf20Sopenharmony_ci event = kzalloc(sizeof(*event), GFP_KERNEL); 17868c2ecf20Sopenharmony_ci if (!event) 17878c2ecf20Sopenharmony_ci return -ENOMEM; 17888c2ecf20Sopenharmony_ci 17898c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&event->unaffiliated_list); 17908c2ecf20Sopenharmony_ci xa_init(&event->object_ids); 17918c2ecf20Sopenharmony_ci 17928c2ecf20Sopenharmony_ci err = xa_insert(&devx_event_table->event_xa, 17938c2ecf20Sopenharmony_ci key_level1, 17948c2ecf20Sopenharmony_ci event, 17958c2ecf20Sopenharmony_ci GFP_KERNEL); 17968c2ecf20Sopenharmony_ci if (err) { 17978c2ecf20Sopenharmony_ci kfree(event); 17988c2ecf20Sopenharmony_ci return err; 17998c2ecf20Sopenharmony_ci } 18008c2ecf20Sopenharmony_ci } 18018c2ecf20Sopenharmony_ci 18028c2ecf20Sopenharmony_ci if (!is_level2) 18038c2ecf20Sopenharmony_ci return 0; 18048c2ecf20Sopenharmony_ci 18058c2ecf20Sopenharmony_ci obj_event = xa_load(&event->object_ids, key_level2); 18068c2ecf20Sopenharmony_ci if (!obj_event) { 18078c2ecf20Sopenharmony_ci obj_event = kzalloc(sizeof(*obj_event), GFP_KERNEL); 18088c2ecf20Sopenharmony_ci if (!obj_event) 18098c2ecf20Sopenharmony_ci /* Level1 is valid for future use, no need to free */ 18108c2ecf20Sopenharmony_ci return -ENOMEM; 18118c2ecf20Sopenharmony_ci 18128c2ecf20Sopenharmony_ci err = xa_insert(&event->object_ids, 18138c2ecf20Sopenharmony_ci key_level2, 18148c2ecf20Sopenharmony_ci obj_event, 18158c2ecf20Sopenharmony_ci GFP_KERNEL); 18168c2ecf20Sopenharmony_ci if (err) { 18178c2ecf20Sopenharmony_ci kfree(obj_event); 18188c2ecf20Sopenharmony_ci return err; 18198c2ecf20Sopenharmony_ci } 18208c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&obj_event->obj_sub_list); 18218c2ecf20Sopenharmony_ci } 18228c2ecf20Sopenharmony_ci 18238c2ecf20Sopenharmony_ci return 0; 18248c2ecf20Sopenharmony_ci} 18258c2ecf20Sopenharmony_ci 18268c2ecf20Sopenharmony_cistatic bool is_valid_events_legacy(int num_events, u16 *event_type_num_list, 18278c2ecf20Sopenharmony_ci struct devx_obj *obj) 18288c2ecf20Sopenharmony_ci{ 18298c2ecf20Sopenharmony_ci int i; 18308c2ecf20Sopenharmony_ci 18318c2ecf20Sopenharmony_ci for (i = 0; i < num_events; i++) { 18328c2ecf20Sopenharmony_ci if (obj) { 18338c2ecf20Sopenharmony_ci if (!is_legacy_obj_event_num(event_type_num_list[i])) 18348c2ecf20Sopenharmony_ci return false; 18358c2ecf20Sopenharmony_ci } else if (!is_legacy_unaffiliated_event_num( 18368c2ecf20Sopenharmony_ci event_type_num_list[i])) { 18378c2ecf20Sopenharmony_ci return false; 18388c2ecf20Sopenharmony_ci } 18398c2ecf20Sopenharmony_ci } 18408c2ecf20Sopenharmony_ci 18418c2ecf20Sopenharmony_ci return true; 18428c2ecf20Sopenharmony_ci} 18438c2ecf20Sopenharmony_ci 18448c2ecf20Sopenharmony_ci#define MAX_SUPP_EVENT_NUM 255 18458c2ecf20Sopenharmony_cistatic bool is_valid_events(struct mlx5_core_dev *dev, 18468c2ecf20Sopenharmony_ci int num_events, u16 *event_type_num_list, 18478c2ecf20Sopenharmony_ci struct devx_obj *obj) 18488c2ecf20Sopenharmony_ci{ 18498c2ecf20Sopenharmony_ci __be64 *aff_events; 18508c2ecf20Sopenharmony_ci __be64 *unaff_events; 18518c2ecf20Sopenharmony_ci int mask_entry; 18528c2ecf20Sopenharmony_ci int mask_bit; 18538c2ecf20Sopenharmony_ci int i; 18548c2ecf20Sopenharmony_ci 18558c2ecf20Sopenharmony_ci if (MLX5_CAP_GEN(dev, event_cap)) { 18568c2ecf20Sopenharmony_ci aff_events = MLX5_CAP_DEV_EVENT(dev, 18578c2ecf20Sopenharmony_ci user_affiliated_events); 18588c2ecf20Sopenharmony_ci unaff_events = MLX5_CAP_DEV_EVENT(dev, 18598c2ecf20Sopenharmony_ci user_unaffiliated_events); 18608c2ecf20Sopenharmony_ci } else { 18618c2ecf20Sopenharmony_ci return is_valid_events_legacy(num_events, event_type_num_list, 18628c2ecf20Sopenharmony_ci obj); 18638c2ecf20Sopenharmony_ci } 18648c2ecf20Sopenharmony_ci 18658c2ecf20Sopenharmony_ci for (i = 0; i < num_events; i++) { 18668c2ecf20Sopenharmony_ci if (event_type_num_list[i] > MAX_SUPP_EVENT_NUM) 18678c2ecf20Sopenharmony_ci return false; 18688c2ecf20Sopenharmony_ci 18698c2ecf20Sopenharmony_ci mask_entry = event_type_num_list[i] / 64; 18708c2ecf20Sopenharmony_ci mask_bit = event_type_num_list[i] % 64; 18718c2ecf20Sopenharmony_ci 18728c2ecf20Sopenharmony_ci if (obj) { 18738c2ecf20Sopenharmony_ci /* CQ completion */ 18748c2ecf20Sopenharmony_ci if (event_type_num_list[i] == 0) 18758c2ecf20Sopenharmony_ci continue; 18768c2ecf20Sopenharmony_ci 18778c2ecf20Sopenharmony_ci if (!(be64_to_cpu(aff_events[mask_entry]) & 18788c2ecf20Sopenharmony_ci (1ull << mask_bit))) 18798c2ecf20Sopenharmony_ci return false; 18808c2ecf20Sopenharmony_ci 18818c2ecf20Sopenharmony_ci continue; 18828c2ecf20Sopenharmony_ci } 18838c2ecf20Sopenharmony_ci 18848c2ecf20Sopenharmony_ci if (!(be64_to_cpu(unaff_events[mask_entry]) & 18858c2ecf20Sopenharmony_ci (1ull << mask_bit))) 18868c2ecf20Sopenharmony_ci return false; 18878c2ecf20Sopenharmony_ci } 18888c2ecf20Sopenharmony_ci 18898c2ecf20Sopenharmony_ci return true; 18908c2ecf20Sopenharmony_ci} 18918c2ecf20Sopenharmony_ci 18928c2ecf20Sopenharmony_ci#define MAX_NUM_EVENTS 16 18938c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_SUBSCRIBE_EVENT)( 18948c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 18958c2ecf20Sopenharmony_ci{ 18968c2ecf20Sopenharmony_ci struct ib_uobject *devx_uobj = uverbs_attr_get_uobject( 18978c2ecf20Sopenharmony_ci attrs, 18988c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_OBJ_HANDLE); 18998c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 19008c2ecf20Sopenharmony_ci &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 19018c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 19028c2ecf20Sopenharmony_ci struct ib_uobject *fd_uobj; 19038c2ecf20Sopenharmony_ci struct devx_obj *obj = NULL; 19048c2ecf20Sopenharmony_ci struct devx_async_event_file *ev_file; 19058c2ecf20Sopenharmony_ci struct mlx5_devx_event_table *devx_event_table = &dev->devx_event_table; 19068c2ecf20Sopenharmony_ci u16 *event_type_num_list; 19078c2ecf20Sopenharmony_ci struct devx_event_subscription *event_sub, *tmp_sub; 19088c2ecf20Sopenharmony_ci struct list_head sub_list; 19098c2ecf20Sopenharmony_ci int redirect_fd; 19108c2ecf20Sopenharmony_ci bool use_eventfd = false; 19118c2ecf20Sopenharmony_ci int num_events; 19128c2ecf20Sopenharmony_ci int num_alloc_xa_entries = 0; 19138c2ecf20Sopenharmony_ci u16 obj_type = 0; 19148c2ecf20Sopenharmony_ci u64 cookie = 0; 19158c2ecf20Sopenharmony_ci u32 obj_id = 0; 19168c2ecf20Sopenharmony_ci int err; 19178c2ecf20Sopenharmony_ci int i; 19188c2ecf20Sopenharmony_ci 19198c2ecf20Sopenharmony_ci if (!c->devx_uid) 19208c2ecf20Sopenharmony_ci return -EINVAL; 19218c2ecf20Sopenharmony_ci 19228c2ecf20Sopenharmony_ci if (!IS_ERR(devx_uobj)) { 19238c2ecf20Sopenharmony_ci obj = (struct devx_obj *)devx_uobj->object; 19248c2ecf20Sopenharmony_ci if (obj) 19258c2ecf20Sopenharmony_ci obj_id = get_dec_obj_id(obj->obj_id); 19268c2ecf20Sopenharmony_ci } 19278c2ecf20Sopenharmony_ci 19288c2ecf20Sopenharmony_ci fd_uobj = uverbs_attr_get_uobject(attrs, 19298c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_FD_HANDLE); 19308c2ecf20Sopenharmony_ci if (IS_ERR(fd_uobj)) 19318c2ecf20Sopenharmony_ci return PTR_ERR(fd_uobj); 19328c2ecf20Sopenharmony_ci 19338c2ecf20Sopenharmony_ci ev_file = container_of(fd_uobj, struct devx_async_event_file, 19348c2ecf20Sopenharmony_ci uobj); 19358c2ecf20Sopenharmony_ci 19368c2ecf20Sopenharmony_ci if (uverbs_attr_is_valid(attrs, 19378c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_FD_NUM)) { 19388c2ecf20Sopenharmony_ci err = uverbs_copy_from(&redirect_fd, attrs, 19398c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_FD_NUM); 19408c2ecf20Sopenharmony_ci if (err) 19418c2ecf20Sopenharmony_ci return err; 19428c2ecf20Sopenharmony_ci 19438c2ecf20Sopenharmony_ci use_eventfd = true; 19448c2ecf20Sopenharmony_ci } 19458c2ecf20Sopenharmony_ci 19468c2ecf20Sopenharmony_ci if (uverbs_attr_is_valid(attrs, 19478c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_COOKIE)) { 19488c2ecf20Sopenharmony_ci if (use_eventfd) 19498c2ecf20Sopenharmony_ci return -EINVAL; 19508c2ecf20Sopenharmony_ci 19518c2ecf20Sopenharmony_ci err = uverbs_copy_from(&cookie, attrs, 19528c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_COOKIE); 19538c2ecf20Sopenharmony_ci if (err) 19548c2ecf20Sopenharmony_ci return err; 19558c2ecf20Sopenharmony_ci } 19568c2ecf20Sopenharmony_ci 19578c2ecf20Sopenharmony_ci num_events = uverbs_attr_ptr_get_array_size( 19588c2ecf20Sopenharmony_ci attrs, MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_TYPE_NUM_LIST, 19598c2ecf20Sopenharmony_ci sizeof(u16)); 19608c2ecf20Sopenharmony_ci 19618c2ecf20Sopenharmony_ci if (num_events < 0) 19628c2ecf20Sopenharmony_ci return num_events; 19638c2ecf20Sopenharmony_ci 19648c2ecf20Sopenharmony_ci if (num_events > MAX_NUM_EVENTS) 19658c2ecf20Sopenharmony_ci return -EINVAL; 19668c2ecf20Sopenharmony_ci 19678c2ecf20Sopenharmony_ci event_type_num_list = uverbs_attr_get_alloced_ptr(attrs, 19688c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_TYPE_NUM_LIST); 19698c2ecf20Sopenharmony_ci 19708c2ecf20Sopenharmony_ci if (!is_valid_events(dev->mdev, num_events, event_type_num_list, obj)) 19718c2ecf20Sopenharmony_ci return -EINVAL; 19728c2ecf20Sopenharmony_ci 19738c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&sub_list); 19748c2ecf20Sopenharmony_ci 19758c2ecf20Sopenharmony_ci /* Protect from concurrent subscriptions to same XA entries to allow 19768c2ecf20Sopenharmony_ci * both to succeed 19778c2ecf20Sopenharmony_ci */ 19788c2ecf20Sopenharmony_ci mutex_lock(&devx_event_table->event_xa_lock); 19798c2ecf20Sopenharmony_ci for (i = 0; i < num_events; i++) { 19808c2ecf20Sopenharmony_ci u32 key_level1; 19818c2ecf20Sopenharmony_ci 19828c2ecf20Sopenharmony_ci if (obj) 19838c2ecf20Sopenharmony_ci obj_type = get_dec_obj_type(obj, 19848c2ecf20Sopenharmony_ci event_type_num_list[i]); 19858c2ecf20Sopenharmony_ci key_level1 = event_type_num_list[i] | obj_type << 16; 19868c2ecf20Sopenharmony_ci 19878c2ecf20Sopenharmony_ci err = subscribe_event_xa_alloc(devx_event_table, 19888c2ecf20Sopenharmony_ci key_level1, 19898c2ecf20Sopenharmony_ci obj, 19908c2ecf20Sopenharmony_ci obj_id); 19918c2ecf20Sopenharmony_ci if (err) 19928c2ecf20Sopenharmony_ci goto err; 19938c2ecf20Sopenharmony_ci 19948c2ecf20Sopenharmony_ci num_alloc_xa_entries++; 19958c2ecf20Sopenharmony_ci event_sub = kzalloc(sizeof(*event_sub), GFP_KERNEL); 19968c2ecf20Sopenharmony_ci if (!event_sub) { 19978c2ecf20Sopenharmony_ci err = -ENOMEM; 19988c2ecf20Sopenharmony_ci goto err; 19998c2ecf20Sopenharmony_ci } 20008c2ecf20Sopenharmony_ci 20018c2ecf20Sopenharmony_ci list_add_tail(&event_sub->event_list, &sub_list); 20028c2ecf20Sopenharmony_ci uverbs_uobject_get(&ev_file->uobj); 20038c2ecf20Sopenharmony_ci if (use_eventfd) { 20048c2ecf20Sopenharmony_ci event_sub->eventfd = 20058c2ecf20Sopenharmony_ci eventfd_ctx_fdget(redirect_fd); 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_ci if (IS_ERR(event_sub->eventfd)) { 20088c2ecf20Sopenharmony_ci err = PTR_ERR(event_sub->eventfd); 20098c2ecf20Sopenharmony_ci event_sub->eventfd = NULL; 20108c2ecf20Sopenharmony_ci goto err; 20118c2ecf20Sopenharmony_ci } 20128c2ecf20Sopenharmony_ci } 20138c2ecf20Sopenharmony_ci 20148c2ecf20Sopenharmony_ci event_sub->cookie = cookie; 20158c2ecf20Sopenharmony_ci event_sub->ev_file = ev_file; 20168c2ecf20Sopenharmony_ci /* May be needed upon cleanup the devx object/subscription */ 20178c2ecf20Sopenharmony_ci event_sub->xa_key_level1 = key_level1; 20188c2ecf20Sopenharmony_ci event_sub->xa_key_level2 = obj_id; 20198c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&event_sub->obj_list); 20208c2ecf20Sopenharmony_ci } 20218c2ecf20Sopenharmony_ci 20228c2ecf20Sopenharmony_ci /* Once all the allocations and the XA data insertions were done we 20238c2ecf20Sopenharmony_ci * can go ahead and add all the subscriptions to the relevant lists 20248c2ecf20Sopenharmony_ci * without concern of a failure. 20258c2ecf20Sopenharmony_ci */ 20268c2ecf20Sopenharmony_ci list_for_each_entry_safe(event_sub, tmp_sub, &sub_list, event_list) { 20278c2ecf20Sopenharmony_ci struct devx_event *event; 20288c2ecf20Sopenharmony_ci struct devx_obj_event *obj_event; 20298c2ecf20Sopenharmony_ci 20308c2ecf20Sopenharmony_ci list_del_init(&event_sub->event_list); 20318c2ecf20Sopenharmony_ci 20328c2ecf20Sopenharmony_ci spin_lock_irq(&ev_file->lock); 20338c2ecf20Sopenharmony_ci list_add_tail_rcu(&event_sub->file_list, 20348c2ecf20Sopenharmony_ci &ev_file->subscribed_events_list); 20358c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 20368c2ecf20Sopenharmony_ci 20378c2ecf20Sopenharmony_ci event = xa_load(&devx_event_table->event_xa, 20388c2ecf20Sopenharmony_ci event_sub->xa_key_level1); 20398c2ecf20Sopenharmony_ci WARN_ON(!event); 20408c2ecf20Sopenharmony_ci 20418c2ecf20Sopenharmony_ci if (!obj) { 20428c2ecf20Sopenharmony_ci list_add_tail_rcu(&event_sub->xa_list, 20438c2ecf20Sopenharmony_ci &event->unaffiliated_list); 20448c2ecf20Sopenharmony_ci continue; 20458c2ecf20Sopenharmony_ci } 20468c2ecf20Sopenharmony_ci 20478c2ecf20Sopenharmony_ci obj_event = xa_load(&event->object_ids, obj_id); 20488c2ecf20Sopenharmony_ci WARN_ON(!obj_event); 20498c2ecf20Sopenharmony_ci list_add_tail_rcu(&event_sub->xa_list, 20508c2ecf20Sopenharmony_ci &obj_event->obj_sub_list); 20518c2ecf20Sopenharmony_ci list_add_tail_rcu(&event_sub->obj_list, 20528c2ecf20Sopenharmony_ci &obj->event_sub); 20538c2ecf20Sopenharmony_ci } 20548c2ecf20Sopenharmony_ci 20558c2ecf20Sopenharmony_ci mutex_unlock(&devx_event_table->event_xa_lock); 20568c2ecf20Sopenharmony_ci return 0; 20578c2ecf20Sopenharmony_ci 20588c2ecf20Sopenharmony_cierr: 20598c2ecf20Sopenharmony_ci list_for_each_entry_safe(event_sub, tmp_sub, &sub_list, event_list) { 20608c2ecf20Sopenharmony_ci list_del(&event_sub->event_list); 20618c2ecf20Sopenharmony_ci 20628c2ecf20Sopenharmony_ci subscribe_event_xa_dealloc(devx_event_table, 20638c2ecf20Sopenharmony_ci event_sub->xa_key_level1, 20648c2ecf20Sopenharmony_ci obj, 20658c2ecf20Sopenharmony_ci obj_id); 20668c2ecf20Sopenharmony_ci 20678c2ecf20Sopenharmony_ci if (event_sub->eventfd) 20688c2ecf20Sopenharmony_ci eventfd_ctx_put(event_sub->eventfd); 20698c2ecf20Sopenharmony_ci uverbs_uobject_put(&event_sub->ev_file->uobj); 20708c2ecf20Sopenharmony_ci kfree(event_sub); 20718c2ecf20Sopenharmony_ci } 20728c2ecf20Sopenharmony_ci 20738c2ecf20Sopenharmony_ci mutex_unlock(&devx_event_table->event_xa_lock); 20748c2ecf20Sopenharmony_ci return err; 20758c2ecf20Sopenharmony_ci} 20768c2ecf20Sopenharmony_ci 20778c2ecf20Sopenharmony_cistatic int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext, 20788c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs, 20798c2ecf20Sopenharmony_ci struct devx_umem *obj) 20808c2ecf20Sopenharmony_ci{ 20818c2ecf20Sopenharmony_ci u64 addr; 20828c2ecf20Sopenharmony_ci size_t size; 20838c2ecf20Sopenharmony_ci u32 access; 20848c2ecf20Sopenharmony_ci int npages; 20858c2ecf20Sopenharmony_ci int err; 20868c2ecf20Sopenharmony_ci u32 page_mask; 20878c2ecf20Sopenharmony_ci 20888c2ecf20Sopenharmony_ci if (uverbs_copy_from(&addr, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR) || 20898c2ecf20Sopenharmony_ci uverbs_copy_from(&size, attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_LEN)) 20908c2ecf20Sopenharmony_ci return -EFAULT; 20918c2ecf20Sopenharmony_ci 20928c2ecf20Sopenharmony_ci err = uverbs_get_flags32(&access, attrs, 20938c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, 20948c2ecf20Sopenharmony_ci IB_ACCESS_LOCAL_WRITE | 20958c2ecf20Sopenharmony_ci IB_ACCESS_REMOTE_WRITE | 20968c2ecf20Sopenharmony_ci IB_ACCESS_REMOTE_READ); 20978c2ecf20Sopenharmony_ci if (err) 20988c2ecf20Sopenharmony_ci return err; 20998c2ecf20Sopenharmony_ci 21008c2ecf20Sopenharmony_ci err = ib_check_mr_access(access); 21018c2ecf20Sopenharmony_ci if (err) 21028c2ecf20Sopenharmony_ci return err; 21038c2ecf20Sopenharmony_ci 21048c2ecf20Sopenharmony_ci obj->umem = ib_umem_get(&dev->ib_dev, addr, size, access); 21058c2ecf20Sopenharmony_ci if (IS_ERR(obj->umem)) 21068c2ecf20Sopenharmony_ci return PTR_ERR(obj->umem); 21078c2ecf20Sopenharmony_ci 21088c2ecf20Sopenharmony_ci mlx5_ib_cont_pages(obj->umem, obj->umem->address, 21098c2ecf20Sopenharmony_ci MLX5_MKEY_PAGE_SHIFT_MASK, &npages, 21108c2ecf20Sopenharmony_ci &obj->page_shift, &obj->ncont, NULL); 21118c2ecf20Sopenharmony_ci 21128c2ecf20Sopenharmony_ci if (!npages) { 21138c2ecf20Sopenharmony_ci ib_umem_release(obj->umem); 21148c2ecf20Sopenharmony_ci return -EINVAL; 21158c2ecf20Sopenharmony_ci } 21168c2ecf20Sopenharmony_ci 21178c2ecf20Sopenharmony_ci page_mask = (1 << obj->page_shift) - 1; 21188c2ecf20Sopenharmony_ci obj->page_offset = obj->umem->address & page_mask; 21198c2ecf20Sopenharmony_ci 21208c2ecf20Sopenharmony_ci return 0; 21218c2ecf20Sopenharmony_ci} 21228c2ecf20Sopenharmony_ci 21238c2ecf20Sopenharmony_cistatic int devx_umem_reg_cmd_alloc(struct uverbs_attr_bundle *attrs, 21248c2ecf20Sopenharmony_ci struct devx_umem *obj, 21258c2ecf20Sopenharmony_ci struct devx_umem_reg_cmd *cmd) 21268c2ecf20Sopenharmony_ci{ 21278c2ecf20Sopenharmony_ci cmd->inlen = MLX5_ST_SZ_BYTES(create_umem_in) + 21288c2ecf20Sopenharmony_ci (MLX5_ST_SZ_BYTES(mtt) * obj->ncont); 21298c2ecf20Sopenharmony_ci cmd->in = uverbs_zalloc(attrs, cmd->inlen); 21308c2ecf20Sopenharmony_ci return PTR_ERR_OR_ZERO(cmd->in); 21318c2ecf20Sopenharmony_ci} 21328c2ecf20Sopenharmony_ci 21338c2ecf20Sopenharmony_cistatic void devx_umem_reg_cmd_build(struct mlx5_ib_dev *dev, 21348c2ecf20Sopenharmony_ci struct devx_umem *obj, 21358c2ecf20Sopenharmony_ci struct devx_umem_reg_cmd *cmd) 21368c2ecf20Sopenharmony_ci{ 21378c2ecf20Sopenharmony_ci void *umem; 21388c2ecf20Sopenharmony_ci __be64 *mtt; 21398c2ecf20Sopenharmony_ci 21408c2ecf20Sopenharmony_ci umem = MLX5_ADDR_OF(create_umem_in, cmd->in, umem); 21418c2ecf20Sopenharmony_ci mtt = (__be64 *)MLX5_ADDR_OF(umem, umem, mtt); 21428c2ecf20Sopenharmony_ci 21438c2ecf20Sopenharmony_ci MLX5_SET(create_umem_in, cmd->in, opcode, MLX5_CMD_OP_CREATE_UMEM); 21448c2ecf20Sopenharmony_ci MLX5_SET64(umem, umem, num_of_mtt, obj->ncont); 21458c2ecf20Sopenharmony_ci MLX5_SET(umem, umem, log_page_size, obj->page_shift - 21468c2ecf20Sopenharmony_ci MLX5_ADAPTER_PAGE_SHIFT); 21478c2ecf20Sopenharmony_ci MLX5_SET(umem, umem, page_offset, obj->page_offset); 21488c2ecf20Sopenharmony_ci mlx5_ib_populate_pas(dev, obj->umem, obj->page_shift, mtt, 21498c2ecf20Sopenharmony_ci (obj->umem->writable ? MLX5_IB_MTT_WRITE : 0) | 21508c2ecf20Sopenharmony_ci MLX5_IB_MTT_READ); 21518c2ecf20Sopenharmony_ci} 21528c2ecf20Sopenharmony_ci 21538c2ecf20Sopenharmony_cistatic int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_REG)( 21548c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 21558c2ecf20Sopenharmony_ci{ 21568c2ecf20Sopenharmony_ci struct devx_umem_reg_cmd cmd; 21578c2ecf20Sopenharmony_ci struct devx_umem *obj; 21588c2ecf20Sopenharmony_ci struct ib_uobject *uobj = uverbs_attr_get_uobject( 21598c2ecf20Sopenharmony_ci attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE); 21608c2ecf20Sopenharmony_ci u32 obj_id; 21618c2ecf20Sopenharmony_ci struct mlx5_ib_ucontext *c = rdma_udata_to_drv_context( 21628c2ecf20Sopenharmony_ci &attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext); 21638c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device); 21648c2ecf20Sopenharmony_ci int err; 21658c2ecf20Sopenharmony_ci 21668c2ecf20Sopenharmony_ci if (!c->devx_uid) 21678c2ecf20Sopenharmony_ci return -EINVAL; 21688c2ecf20Sopenharmony_ci 21698c2ecf20Sopenharmony_ci obj = kzalloc(sizeof(struct devx_umem), GFP_KERNEL); 21708c2ecf20Sopenharmony_ci if (!obj) 21718c2ecf20Sopenharmony_ci return -ENOMEM; 21728c2ecf20Sopenharmony_ci 21738c2ecf20Sopenharmony_ci err = devx_umem_get(dev, &c->ibucontext, attrs, obj); 21748c2ecf20Sopenharmony_ci if (err) 21758c2ecf20Sopenharmony_ci goto err_obj_free; 21768c2ecf20Sopenharmony_ci 21778c2ecf20Sopenharmony_ci err = devx_umem_reg_cmd_alloc(attrs, obj, &cmd); 21788c2ecf20Sopenharmony_ci if (err) 21798c2ecf20Sopenharmony_ci goto err_umem_release; 21808c2ecf20Sopenharmony_ci 21818c2ecf20Sopenharmony_ci devx_umem_reg_cmd_build(dev, obj, &cmd); 21828c2ecf20Sopenharmony_ci 21838c2ecf20Sopenharmony_ci MLX5_SET(create_umem_in, cmd.in, uid, c->devx_uid); 21848c2ecf20Sopenharmony_ci err = mlx5_cmd_exec(dev->mdev, cmd.in, cmd.inlen, cmd.out, 21858c2ecf20Sopenharmony_ci sizeof(cmd.out)); 21868c2ecf20Sopenharmony_ci if (err) 21878c2ecf20Sopenharmony_ci goto err_umem_release; 21888c2ecf20Sopenharmony_ci 21898c2ecf20Sopenharmony_ci obj->mdev = dev->mdev; 21908c2ecf20Sopenharmony_ci uobj->object = obj; 21918c2ecf20Sopenharmony_ci devx_obj_build_destroy_cmd(cmd.in, cmd.out, obj->dinbox, &obj->dinlen, &obj_id); 21928c2ecf20Sopenharmony_ci uverbs_finalize_uobj_create(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE); 21938c2ecf20Sopenharmony_ci 21948c2ecf20Sopenharmony_ci err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, &obj_id, 21958c2ecf20Sopenharmony_ci sizeof(obj_id)); 21968c2ecf20Sopenharmony_ci return err; 21978c2ecf20Sopenharmony_ci 21988c2ecf20Sopenharmony_cierr_umem_release: 21998c2ecf20Sopenharmony_ci ib_umem_release(obj->umem); 22008c2ecf20Sopenharmony_cierr_obj_free: 22018c2ecf20Sopenharmony_ci kfree(obj); 22028c2ecf20Sopenharmony_ci return err; 22038c2ecf20Sopenharmony_ci} 22048c2ecf20Sopenharmony_ci 22058c2ecf20Sopenharmony_cistatic int devx_umem_cleanup(struct ib_uobject *uobject, 22068c2ecf20Sopenharmony_ci enum rdma_remove_reason why, 22078c2ecf20Sopenharmony_ci struct uverbs_attr_bundle *attrs) 22088c2ecf20Sopenharmony_ci{ 22098c2ecf20Sopenharmony_ci struct devx_umem *obj = uobject->object; 22108c2ecf20Sopenharmony_ci u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 22118c2ecf20Sopenharmony_ci int err; 22128c2ecf20Sopenharmony_ci 22138c2ecf20Sopenharmony_ci err = mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out)); 22148c2ecf20Sopenharmony_ci if (ib_is_destroy_retryable(err, why, uobject)) 22158c2ecf20Sopenharmony_ci return err; 22168c2ecf20Sopenharmony_ci 22178c2ecf20Sopenharmony_ci ib_umem_release(obj->umem); 22188c2ecf20Sopenharmony_ci kfree(obj); 22198c2ecf20Sopenharmony_ci return 0; 22208c2ecf20Sopenharmony_ci} 22218c2ecf20Sopenharmony_ci 22228c2ecf20Sopenharmony_cistatic bool is_unaffiliated_event(struct mlx5_core_dev *dev, 22238c2ecf20Sopenharmony_ci unsigned long event_type) 22248c2ecf20Sopenharmony_ci{ 22258c2ecf20Sopenharmony_ci __be64 *unaff_events; 22268c2ecf20Sopenharmony_ci int mask_entry; 22278c2ecf20Sopenharmony_ci int mask_bit; 22288c2ecf20Sopenharmony_ci 22298c2ecf20Sopenharmony_ci if (!MLX5_CAP_GEN(dev, event_cap)) 22308c2ecf20Sopenharmony_ci return is_legacy_unaffiliated_event_num(event_type); 22318c2ecf20Sopenharmony_ci 22328c2ecf20Sopenharmony_ci unaff_events = MLX5_CAP_DEV_EVENT(dev, 22338c2ecf20Sopenharmony_ci user_unaffiliated_events); 22348c2ecf20Sopenharmony_ci WARN_ON(event_type > MAX_SUPP_EVENT_NUM); 22358c2ecf20Sopenharmony_ci 22368c2ecf20Sopenharmony_ci mask_entry = event_type / 64; 22378c2ecf20Sopenharmony_ci mask_bit = event_type % 64; 22388c2ecf20Sopenharmony_ci 22398c2ecf20Sopenharmony_ci if (!(be64_to_cpu(unaff_events[mask_entry]) & (1ull << mask_bit))) 22408c2ecf20Sopenharmony_ci return false; 22418c2ecf20Sopenharmony_ci 22428c2ecf20Sopenharmony_ci return true; 22438c2ecf20Sopenharmony_ci} 22448c2ecf20Sopenharmony_ci 22458c2ecf20Sopenharmony_cistatic u32 devx_get_obj_id_from_event(unsigned long event_type, void *data) 22468c2ecf20Sopenharmony_ci{ 22478c2ecf20Sopenharmony_ci struct mlx5_eqe *eqe = data; 22488c2ecf20Sopenharmony_ci u32 obj_id = 0; 22498c2ecf20Sopenharmony_ci 22508c2ecf20Sopenharmony_ci switch (event_type) { 22518c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR: 22528c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT: 22538c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_PATH_MIG: 22548c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_COMM_EST: 22558c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SQ_DRAINED: 22568c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_SRQ_LAST_WQE: 22578c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_CATAS_ERROR: 22588c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_PATH_MIG_FAILED: 22598c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR: 22608c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR: 22618c2ecf20Sopenharmony_ci obj_id = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff; 22628c2ecf20Sopenharmony_ci break; 22638c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_XRQ_ERROR: 22648c2ecf20Sopenharmony_ci obj_id = be32_to_cpu(eqe->data.xrq_err.type_xrqn) & 0xffffff; 22658c2ecf20Sopenharmony_ci break; 22668c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_DCT_DRAINED: 22678c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_DCT_KEY_VIOLATION: 22688c2ecf20Sopenharmony_ci obj_id = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff; 22698c2ecf20Sopenharmony_ci break; 22708c2ecf20Sopenharmony_ci case MLX5_EVENT_TYPE_CQ_ERROR: 22718c2ecf20Sopenharmony_ci obj_id = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff; 22728c2ecf20Sopenharmony_ci break; 22738c2ecf20Sopenharmony_ci default: 22748c2ecf20Sopenharmony_ci obj_id = MLX5_GET(affiliated_event_header, &eqe->data, obj_id); 22758c2ecf20Sopenharmony_ci break; 22768c2ecf20Sopenharmony_ci } 22778c2ecf20Sopenharmony_ci 22788c2ecf20Sopenharmony_ci return obj_id; 22798c2ecf20Sopenharmony_ci} 22808c2ecf20Sopenharmony_ci 22818c2ecf20Sopenharmony_cistatic int deliver_event(struct devx_event_subscription *event_sub, 22828c2ecf20Sopenharmony_ci const void *data) 22838c2ecf20Sopenharmony_ci{ 22848c2ecf20Sopenharmony_ci struct devx_async_event_file *ev_file; 22858c2ecf20Sopenharmony_ci struct devx_async_event_data *event_data; 22868c2ecf20Sopenharmony_ci unsigned long flags; 22878c2ecf20Sopenharmony_ci 22888c2ecf20Sopenharmony_ci ev_file = event_sub->ev_file; 22898c2ecf20Sopenharmony_ci 22908c2ecf20Sopenharmony_ci if (ev_file->omit_data) { 22918c2ecf20Sopenharmony_ci spin_lock_irqsave(&ev_file->lock, flags); 22928c2ecf20Sopenharmony_ci if (!list_empty(&event_sub->event_list) || 22938c2ecf20Sopenharmony_ci ev_file->is_destroyed) { 22948c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ev_file->lock, flags); 22958c2ecf20Sopenharmony_ci return 0; 22968c2ecf20Sopenharmony_ci } 22978c2ecf20Sopenharmony_ci 22988c2ecf20Sopenharmony_ci list_add_tail(&event_sub->event_list, &ev_file->event_list); 22998c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ev_file->lock, flags); 23008c2ecf20Sopenharmony_ci wake_up_interruptible(&ev_file->poll_wait); 23018c2ecf20Sopenharmony_ci return 0; 23028c2ecf20Sopenharmony_ci } 23038c2ecf20Sopenharmony_ci 23048c2ecf20Sopenharmony_ci event_data = kzalloc(sizeof(*event_data) + sizeof(struct mlx5_eqe), 23058c2ecf20Sopenharmony_ci GFP_ATOMIC); 23068c2ecf20Sopenharmony_ci if (!event_data) { 23078c2ecf20Sopenharmony_ci spin_lock_irqsave(&ev_file->lock, flags); 23088c2ecf20Sopenharmony_ci ev_file->is_overflow_err = 1; 23098c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ev_file->lock, flags); 23108c2ecf20Sopenharmony_ci return -ENOMEM; 23118c2ecf20Sopenharmony_ci } 23128c2ecf20Sopenharmony_ci 23138c2ecf20Sopenharmony_ci event_data->hdr.cookie = event_sub->cookie; 23148c2ecf20Sopenharmony_ci memcpy(event_data->hdr.out_data, data, sizeof(struct mlx5_eqe)); 23158c2ecf20Sopenharmony_ci 23168c2ecf20Sopenharmony_ci spin_lock_irqsave(&ev_file->lock, flags); 23178c2ecf20Sopenharmony_ci if (!ev_file->is_destroyed) 23188c2ecf20Sopenharmony_ci list_add_tail(&event_data->list, &ev_file->event_list); 23198c2ecf20Sopenharmony_ci else 23208c2ecf20Sopenharmony_ci kfree(event_data); 23218c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ev_file->lock, flags); 23228c2ecf20Sopenharmony_ci wake_up_interruptible(&ev_file->poll_wait); 23238c2ecf20Sopenharmony_ci 23248c2ecf20Sopenharmony_ci return 0; 23258c2ecf20Sopenharmony_ci} 23268c2ecf20Sopenharmony_ci 23278c2ecf20Sopenharmony_cistatic void dispatch_event_fd(struct list_head *fd_list, 23288c2ecf20Sopenharmony_ci const void *data) 23298c2ecf20Sopenharmony_ci{ 23308c2ecf20Sopenharmony_ci struct devx_event_subscription *item; 23318c2ecf20Sopenharmony_ci 23328c2ecf20Sopenharmony_ci list_for_each_entry_rcu(item, fd_list, xa_list) { 23338c2ecf20Sopenharmony_ci if (item->eventfd) 23348c2ecf20Sopenharmony_ci eventfd_signal(item->eventfd, 1); 23358c2ecf20Sopenharmony_ci else 23368c2ecf20Sopenharmony_ci deliver_event(item, data); 23378c2ecf20Sopenharmony_ci } 23388c2ecf20Sopenharmony_ci} 23398c2ecf20Sopenharmony_ci 23408c2ecf20Sopenharmony_cistatic int devx_event_notifier(struct notifier_block *nb, 23418c2ecf20Sopenharmony_ci unsigned long event_type, void *data) 23428c2ecf20Sopenharmony_ci{ 23438c2ecf20Sopenharmony_ci struct mlx5_devx_event_table *table; 23448c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev; 23458c2ecf20Sopenharmony_ci struct devx_event *event; 23468c2ecf20Sopenharmony_ci struct devx_obj_event *obj_event; 23478c2ecf20Sopenharmony_ci u16 obj_type = 0; 23488c2ecf20Sopenharmony_ci bool is_unaffiliated; 23498c2ecf20Sopenharmony_ci u32 obj_id; 23508c2ecf20Sopenharmony_ci 23518c2ecf20Sopenharmony_ci /* Explicit filtering to kernel events which may occur frequently */ 23528c2ecf20Sopenharmony_ci if (event_type == MLX5_EVENT_TYPE_CMD || 23538c2ecf20Sopenharmony_ci event_type == MLX5_EVENT_TYPE_PAGE_REQUEST) 23548c2ecf20Sopenharmony_ci return NOTIFY_OK; 23558c2ecf20Sopenharmony_ci 23568c2ecf20Sopenharmony_ci table = container_of(nb, struct mlx5_devx_event_table, devx_nb.nb); 23578c2ecf20Sopenharmony_ci dev = container_of(table, struct mlx5_ib_dev, devx_event_table); 23588c2ecf20Sopenharmony_ci is_unaffiliated = is_unaffiliated_event(dev->mdev, event_type); 23598c2ecf20Sopenharmony_ci 23608c2ecf20Sopenharmony_ci if (!is_unaffiliated) 23618c2ecf20Sopenharmony_ci obj_type = get_event_obj_type(event_type, data); 23628c2ecf20Sopenharmony_ci 23638c2ecf20Sopenharmony_ci rcu_read_lock(); 23648c2ecf20Sopenharmony_ci event = xa_load(&table->event_xa, event_type | (obj_type << 16)); 23658c2ecf20Sopenharmony_ci if (!event) { 23668c2ecf20Sopenharmony_ci rcu_read_unlock(); 23678c2ecf20Sopenharmony_ci return NOTIFY_DONE; 23688c2ecf20Sopenharmony_ci } 23698c2ecf20Sopenharmony_ci 23708c2ecf20Sopenharmony_ci if (is_unaffiliated) { 23718c2ecf20Sopenharmony_ci dispatch_event_fd(&event->unaffiliated_list, data); 23728c2ecf20Sopenharmony_ci rcu_read_unlock(); 23738c2ecf20Sopenharmony_ci return NOTIFY_OK; 23748c2ecf20Sopenharmony_ci } 23758c2ecf20Sopenharmony_ci 23768c2ecf20Sopenharmony_ci obj_id = devx_get_obj_id_from_event(event_type, data); 23778c2ecf20Sopenharmony_ci obj_event = xa_load(&event->object_ids, obj_id); 23788c2ecf20Sopenharmony_ci if (!obj_event) { 23798c2ecf20Sopenharmony_ci rcu_read_unlock(); 23808c2ecf20Sopenharmony_ci return NOTIFY_DONE; 23818c2ecf20Sopenharmony_ci } 23828c2ecf20Sopenharmony_ci 23838c2ecf20Sopenharmony_ci dispatch_event_fd(&obj_event->obj_sub_list, data); 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_ci rcu_read_unlock(); 23868c2ecf20Sopenharmony_ci return NOTIFY_OK; 23878c2ecf20Sopenharmony_ci} 23888c2ecf20Sopenharmony_ci 23898c2ecf20Sopenharmony_ciint mlx5_ib_devx_init(struct mlx5_ib_dev *dev) 23908c2ecf20Sopenharmony_ci{ 23918c2ecf20Sopenharmony_ci struct mlx5_devx_event_table *table = &dev->devx_event_table; 23928c2ecf20Sopenharmony_ci int uid; 23938c2ecf20Sopenharmony_ci 23948c2ecf20Sopenharmony_ci uid = mlx5_ib_devx_create(dev, false); 23958c2ecf20Sopenharmony_ci if (uid > 0) { 23968c2ecf20Sopenharmony_ci dev->devx_whitelist_uid = uid; 23978c2ecf20Sopenharmony_ci xa_init(&table->event_xa); 23988c2ecf20Sopenharmony_ci mutex_init(&table->event_xa_lock); 23998c2ecf20Sopenharmony_ci MLX5_NB_INIT(&table->devx_nb, devx_event_notifier, NOTIFY_ANY); 24008c2ecf20Sopenharmony_ci mlx5_eq_notifier_register(dev->mdev, &table->devx_nb); 24018c2ecf20Sopenharmony_ci } 24028c2ecf20Sopenharmony_ci 24038c2ecf20Sopenharmony_ci return 0; 24048c2ecf20Sopenharmony_ci} 24058c2ecf20Sopenharmony_ci 24068c2ecf20Sopenharmony_civoid mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev) 24078c2ecf20Sopenharmony_ci{ 24088c2ecf20Sopenharmony_ci struct mlx5_devx_event_table *table = &dev->devx_event_table; 24098c2ecf20Sopenharmony_ci struct devx_event_subscription *sub, *tmp; 24108c2ecf20Sopenharmony_ci struct devx_event *event; 24118c2ecf20Sopenharmony_ci void *entry; 24128c2ecf20Sopenharmony_ci unsigned long id; 24138c2ecf20Sopenharmony_ci 24148c2ecf20Sopenharmony_ci if (dev->devx_whitelist_uid) { 24158c2ecf20Sopenharmony_ci mlx5_eq_notifier_unregister(dev->mdev, &table->devx_nb); 24168c2ecf20Sopenharmony_ci mutex_lock(&dev->devx_event_table.event_xa_lock); 24178c2ecf20Sopenharmony_ci xa_for_each(&table->event_xa, id, entry) { 24188c2ecf20Sopenharmony_ci event = entry; 24198c2ecf20Sopenharmony_ci list_for_each_entry_safe( 24208c2ecf20Sopenharmony_ci sub, tmp, &event->unaffiliated_list, xa_list) 24218c2ecf20Sopenharmony_ci devx_cleanup_subscription(dev, sub); 24228c2ecf20Sopenharmony_ci kfree(entry); 24238c2ecf20Sopenharmony_ci } 24248c2ecf20Sopenharmony_ci mutex_unlock(&dev->devx_event_table.event_xa_lock); 24258c2ecf20Sopenharmony_ci xa_destroy(&table->event_xa); 24268c2ecf20Sopenharmony_ci 24278c2ecf20Sopenharmony_ci mlx5_ib_devx_destroy(dev, dev->devx_whitelist_uid); 24288c2ecf20Sopenharmony_ci } 24298c2ecf20Sopenharmony_ci} 24308c2ecf20Sopenharmony_ci 24318c2ecf20Sopenharmony_cistatic ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf, 24328c2ecf20Sopenharmony_ci size_t count, loff_t *pos) 24338c2ecf20Sopenharmony_ci{ 24348c2ecf20Sopenharmony_ci struct devx_async_cmd_event_file *comp_ev_file = filp->private_data; 24358c2ecf20Sopenharmony_ci struct devx_async_event_queue *ev_queue = &comp_ev_file->ev_queue; 24368c2ecf20Sopenharmony_ci struct devx_async_data *event; 24378c2ecf20Sopenharmony_ci int ret = 0; 24388c2ecf20Sopenharmony_ci size_t eventsz; 24398c2ecf20Sopenharmony_ci 24408c2ecf20Sopenharmony_ci spin_lock_irq(&ev_queue->lock); 24418c2ecf20Sopenharmony_ci 24428c2ecf20Sopenharmony_ci while (list_empty(&ev_queue->event_list)) { 24438c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_queue->lock); 24448c2ecf20Sopenharmony_ci 24458c2ecf20Sopenharmony_ci if (filp->f_flags & O_NONBLOCK) 24468c2ecf20Sopenharmony_ci return -EAGAIN; 24478c2ecf20Sopenharmony_ci 24488c2ecf20Sopenharmony_ci if (wait_event_interruptible( 24498c2ecf20Sopenharmony_ci ev_queue->poll_wait, 24508c2ecf20Sopenharmony_ci (!list_empty(&ev_queue->event_list) || 24518c2ecf20Sopenharmony_ci ev_queue->is_destroyed))) { 24528c2ecf20Sopenharmony_ci return -ERESTARTSYS; 24538c2ecf20Sopenharmony_ci } 24548c2ecf20Sopenharmony_ci 24558c2ecf20Sopenharmony_ci spin_lock_irq(&ev_queue->lock); 24568c2ecf20Sopenharmony_ci if (ev_queue->is_destroyed) { 24578c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_queue->lock); 24588c2ecf20Sopenharmony_ci return -EIO; 24598c2ecf20Sopenharmony_ci } 24608c2ecf20Sopenharmony_ci } 24618c2ecf20Sopenharmony_ci 24628c2ecf20Sopenharmony_ci event = list_entry(ev_queue->event_list.next, 24638c2ecf20Sopenharmony_ci struct devx_async_data, list); 24648c2ecf20Sopenharmony_ci eventsz = event->cmd_out_len + 24658c2ecf20Sopenharmony_ci sizeof(struct mlx5_ib_uapi_devx_async_cmd_hdr); 24668c2ecf20Sopenharmony_ci 24678c2ecf20Sopenharmony_ci if (eventsz > count) { 24688c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_queue->lock); 24698c2ecf20Sopenharmony_ci return -ENOSPC; 24708c2ecf20Sopenharmony_ci } 24718c2ecf20Sopenharmony_ci 24728c2ecf20Sopenharmony_ci list_del(ev_queue->event_list.next); 24738c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_queue->lock); 24748c2ecf20Sopenharmony_ci 24758c2ecf20Sopenharmony_ci if (copy_to_user(buf, &event->hdr, eventsz)) 24768c2ecf20Sopenharmony_ci ret = -EFAULT; 24778c2ecf20Sopenharmony_ci else 24788c2ecf20Sopenharmony_ci ret = eventsz; 24798c2ecf20Sopenharmony_ci 24808c2ecf20Sopenharmony_ci atomic_sub(event->cmd_out_len, &ev_queue->bytes_in_use); 24818c2ecf20Sopenharmony_ci kvfree(event); 24828c2ecf20Sopenharmony_ci return ret; 24838c2ecf20Sopenharmony_ci} 24848c2ecf20Sopenharmony_ci 24858c2ecf20Sopenharmony_cistatic __poll_t devx_async_cmd_event_poll(struct file *filp, 24868c2ecf20Sopenharmony_ci struct poll_table_struct *wait) 24878c2ecf20Sopenharmony_ci{ 24888c2ecf20Sopenharmony_ci struct devx_async_cmd_event_file *comp_ev_file = filp->private_data; 24898c2ecf20Sopenharmony_ci struct devx_async_event_queue *ev_queue = &comp_ev_file->ev_queue; 24908c2ecf20Sopenharmony_ci __poll_t pollflags = 0; 24918c2ecf20Sopenharmony_ci 24928c2ecf20Sopenharmony_ci poll_wait(filp, &ev_queue->poll_wait, wait); 24938c2ecf20Sopenharmony_ci 24948c2ecf20Sopenharmony_ci spin_lock_irq(&ev_queue->lock); 24958c2ecf20Sopenharmony_ci if (ev_queue->is_destroyed) 24968c2ecf20Sopenharmony_ci pollflags = EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; 24978c2ecf20Sopenharmony_ci else if (!list_empty(&ev_queue->event_list)) 24988c2ecf20Sopenharmony_ci pollflags = EPOLLIN | EPOLLRDNORM; 24998c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_queue->lock); 25008c2ecf20Sopenharmony_ci 25018c2ecf20Sopenharmony_ci return pollflags; 25028c2ecf20Sopenharmony_ci} 25038c2ecf20Sopenharmony_ci 25048c2ecf20Sopenharmony_cistatic const struct file_operations devx_async_cmd_event_fops = { 25058c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 25068c2ecf20Sopenharmony_ci .read = devx_async_cmd_event_read, 25078c2ecf20Sopenharmony_ci .poll = devx_async_cmd_event_poll, 25088c2ecf20Sopenharmony_ci .release = uverbs_uobject_fd_release, 25098c2ecf20Sopenharmony_ci .llseek = no_llseek, 25108c2ecf20Sopenharmony_ci}; 25118c2ecf20Sopenharmony_ci 25128c2ecf20Sopenharmony_cistatic ssize_t devx_async_event_read(struct file *filp, char __user *buf, 25138c2ecf20Sopenharmony_ci size_t count, loff_t *pos) 25148c2ecf20Sopenharmony_ci{ 25158c2ecf20Sopenharmony_ci struct devx_async_event_file *ev_file = filp->private_data; 25168c2ecf20Sopenharmony_ci struct devx_event_subscription *event_sub; 25178c2ecf20Sopenharmony_ci struct devx_async_event_data *event; 25188c2ecf20Sopenharmony_ci int ret = 0; 25198c2ecf20Sopenharmony_ci size_t eventsz; 25208c2ecf20Sopenharmony_ci bool omit_data; 25218c2ecf20Sopenharmony_ci void *event_data; 25228c2ecf20Sopenharmony_ci 25238c2ecf20Sopenharmony_ci omit_data = ev_file->omit_data; 25248c2ecf20Sopenharmony_ci 25258c2ecf20Sopenharmony_ci spin_lock_irq(&ev_file->lock); 25268c2ecf20Sopenharmony_ci 25278c2ecf20Sopenharmony_ci if (ev_file->is_overflow_err) { 25288c2ecf20Sopenharmony_ci ev_file->is_overflow_err = 0; 25298c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 25308c2ecf20Sopenharmony_ci return -EOVERFLOW; 25318c2ecf20Sopenharmony_ci } 25328c2ecf20Sopenharmony_ci 25338c2ecf20Sopenharmony_ci 25348c2ecf20Sopenharmony_ci while (list_empty(&ev_file->event_list)) { 25358c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 25368c2ecf20Sopenharmony_ci 25378c2ecf20Sopenharmony_ci if (filp->f_flags & O_NONBLOCK) 25388c2ecf20Sopenharmony_ci return -EAGAIN; 25398c2ecf20Sopenharmony_ci 25408c2ecf20Sopenharmony_ci if (wait_event_interruptible(ev_file->poll_wait, 25418c2ecf20Sopenharmony_ci (!list_empty(&ev_file->event_list) || 25428c2ecf20Sopenharmony_ci ev_file->is_destroyed))) { 25438c2ecf20Sopenharmony_ci return -ERESTARTSYS; 25448c2ecf20Sopenharmony_ci } 25458c2ecf20Sopenharmony_ci 25468c2ecf20Sopenharmony_ci spin_lock_irq(&ev_file->lock); 25478c2ecf20Sopenharmony_ci if (ev_file->is_destroyed) { 25488c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 25498c2ecf20Sopenharmony_ci return -EIO; 25508c2ecf20Sopenharmony_ci } 25518c2ecf20Sopenharmony_ci } 25528c2ecf20Sopenharmony_ci 25538c2ecf20Sopenharmony_ci if (omit_data) { 25548c2ecf20Sopenharmony_ci event_sub = list_first_entry(&ev_file->event_list, 25558c2ecf20Sopenharmony_ci struct devx_event_subscription, 25568c2ecf20Sopenharmony_ci event_list); 25578c2ecf20Sopenharmony_ci eventsz = sizeof(event_sub->cookie); 25588c2ecf20Sopenharmony_ci event_data = &event_sub->cookie; 25598c2ecf20Sopenharmony_ci } else { 25608c2ecf20Sopenharmony_ci event = list_first_entry(&ev_file->event_list, 25618c2ecf20Sopenharmony_ci struct devx_async_event_data, list); 25628c2ecf20Sopenharmony_ci eventsz = sizeof(struct mlx5_eqe) + 25638c2ecf20Sopenharmony_ci sizeof(struct mlx5_ib_uapi_devx_async_event_hdr); 25648c2ecf20Sopenharmony_ci event_data = &event->hdr; 25658c2ecf20Sopenharmony_ci } 25668c2ecf20Sopenharmony_ci 25678c2ecf20Sopenharmony_ci if (eventsz > count) { 25688c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 25698c2ecf20Sopenharmony_ci return -EINVAL; 25708c2ecf20Sopenharmony_ci } 25718c2ecf20Sopenharmony_ci 25728c2ecf20Sopenharmony_ci if (omit_data) 25738c2ecf20Sopenharmony_ci list_del_init(&event_sub->event_list); 25748c2ecf20Sopenharmony_ci else 25758c2ecf20Sopenharmony_ci list_del(&event->list); 25768c2ecf20Sopenharmony_ci 25778c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 25788c2ecf20Sopenharmony_ci 25798c2ecf20Sopenharmony_ci if (copy_to_user(buf, event_data, eventsz)) 25808c2ecf20Sopenharmony_ci /* This points to an application issue, not a kernel concern */ 25818c2ecf20Sopenharmony_ci ret = -EFAULT; 25828c2ecf20Sopenharmony_ci else 25838c2ecf20Sopenharmony_ci ret = eventsz; 25848c2ecf20Sopenharmony_ci 25858c2ecf20Sopenharmony_ci if (!omit_data) 25868c2ecf20Sopenharmony_ci kfree(event); 25878c2ecf20Sopenharmony_ci return ret; 25888c2ecf20Sopenharmony_ci} 25898c2ecf20Sopenharmony_ci 25908c2ecf20Sopenharmony_cistatic __poll_t devx_async_event_poll(struct file *filp, 25918c2ecf20Sopenharmony_ci struct poll_table_struct *wait) 25928c2ecf20Sopenharmony_ci{ 25938c2ecf20Sopenharmony_ci struct devx_async_event_file *ev_file = filp->private_data; 25948c2ecf20Sopenharmony_ci __poll_t pollflags = 0; 25958c2ecf20Sopenharmony_ci 25968c2ecf20Sopenharmony_ci poll_wait(filp, &ev_file->poll_wait, wait); 25978c2ecf20Sopenharmony_ci 25988c2ecf20Sopenharmony_ci spin_lock_irq(&ev_file->lock); 25998c2ecf20Sopenharmony_ci if (ev_file->is_destroyed) 26008c2ecf20Sopenharmony_ci pollflags = EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; 26018c2ecf20Sopenharmony_ci else if (!list_empty(&ev_file->event_list)) 26028c2ecf20Sopenharmony_ci pollflags = EPOLLIN | EPOLLRDNORM; 26038c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 26048c2ecf20Sopenharmony_ci 26058c2ecf20Sopenharmony_ci return pollflags; 26068c2ecf20Sopenharmony_ci} 26078c2ecf20Sopenharmony_ci 26088c2ecf20Sopenharmony_cistatic void devx_free_subscription(struct rcu_head *rcu) 26098c2ecf20Sopenharmony_ci{ 26108c2ecf20Sopenharmony_ci struct devx_event_subscription *event_sub = 26118c2ecf20Sopenharmony_ci container_of(rcu, struct devx_event_subscription, rcu); 26128c2ecf20Sopenharmony_ci 26138c2ecf20Sopenharmony_ci if (event_sub->eventfd) 26148c2ecf20Sopenharmony_ci eventfd_ctx_put(event_sub->eventfd); 26158c2ecf20Sopenharmony_ci uverbs_uobject_put(&event_sub->ev_file->uobj); 26168c2ecf20Sopenharmony_ci kfree(event_sub); 26178c2ecf20Sopenharmony_ci} 26188c2ecf20Sopenharmony_ci 26198c2ecf20Sopenharmony_cistatic const struct file_operations devx_async_event_fops = { 26208c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 26218c2ecf20Sopenharmony_ci .read = devx_async_event_read, 26228c2ecf20Sopenharmony_ci .poll = devx_async_event_poll, 26238c2ecf20Sopenharmony_ci .release = uverbs_uobject_fd_release, 26248c2ecf20Sopenharmony_ci .llseek = no_llseek, 26258c2ecf20Sopenharmony_ci}; 26268c2ecf20Sopenharmony_ci 26278c2ecf20Sopenharmony_cistatic int devx_async_cmd_event_destroy_uobj(struct ib_uobject *uobj, 26288c2ecf20Sopenharmony_ci enum rdma_remove_reason why) 26298c2ecf20Sopenharmony_ci{ 26308c2ecf20Sopenharmony_ci struct devx_async_cmd_event_file *comp_ev_file = 26318c2ecf20Sopenharmony_ci container_of(uobj, struct devx_async_cmd_event_file, 26328c2ecf20Sopenharmony_ci uobj); 26338c2ecf20Sopenharmony_ci struct devx_async_event_queue *ev_queue = &comp_ev_file->ev_queue; 26348c2ecf20Sopenharmony_ci struct devx_async_data *entry, *tmp; 26358c2ecf20Sopenharmony_ci 26368c2ecf20Sopenharmony_ci spin_lock_irq(&ev_queue->lock); 26378c2ecf20Sopenharmony_ci ev_queue->is_destroyed = 1; 26388c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_queue->lock); 26398c2ecf20Sopenharmony_ci wake_up_interruptible(&ev_queue->poll_wait); 26408c2ecf20Sopenharmony_ci 26418c2ecf20Sopenharmony_ci mlx5_cmd_cleanup_async_ctx(&comp_ev_file->async_ctx); 26428c2ecf20Sopenharmony_ci 26438c2ecf20Sopenharmony_ci spin_lock_irq(&comp_ev_file->ev_queue.lock); 26448c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, tmp, 26458c2ecf20Sopenharmony_ci &comp_ev_file->ev_queue.event_list, list) { 26468c2ecf20Sopenharmony_ci list_del(&entry->list); 26478c2ecf20Sopenharmony_ci kvfree(entry); 26488c2ecf20Sopenharmony_ci } 26498c2ecf20Sopenharmony_ci spin_unlock_irq(&comp_ev_file->ev_queue.lock); 26508c2ecf20Sopenharmony_ci return 0; 26518c2ecf20Sopenharmony_ci}; 26528c2ecf20Sopenharmony_ci 26538c2ecf20Sopenharmony_cistatic int devx_async_event_destroy_uobj(struct ib_uobject *uobj, 26548c2ecf20Sopenharmony_ci enum rdma_remove_reason why) 26558c2ecf20Sopenharmony_ci{ 26568c2ecf20Sopenharmony_ci struct devx_async_event_file *ev_file = 26578c2ecf20Sopenharmony_ci container_of(uobj, struct devx_async_event_file, 26588c2ecf20Sopenharmony_ci uobj); 26598c2ecf20Sopenharmony_ci struct devx_event_subscription *event_sub, *event_sub_tmp; 26608c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev = ev_file->dev; 26618c2ecf20Sopenharmony_ci 26628c2ecf20Sopenharmony_ci spin_lock_irq(&ev_file->lock); 26638c2ecf20Sopenharmony_ci ev_file->is_destroyed = 1; 26648c2ecf20Sopenharmony_ci 26658c2ecf20Sopenharmony_ci /* free the pending events allocation */ 26668c2ecf20Sopenharmony_ci if (ev_file->omit_data) { 26678c2ecf20Sopenharmony_ci struct devx_event_subscription *event_sub, *tmp; 26688c2ecf20Sopenharmony_ci 26698c2ecf20Sopenharmony_ci list_for_each_entry_safe(event_sub, tmp, &ev_file->event_list, 26708c2ecf20Sopenharmony_ci event_list) 26718c2ecf20Sopenharmony_ci list_del_init(&event_sub->event_list); 26728c2ecf20Sopenharmony_ci 26738c2ecf20Sopenharmony_ci } else { 26748c2ecf20Sopenharmony_ci struct devx_async_event_data *entry, *tmp; 26758c2ecf20Sopenharmony_ci 26768c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, tmp, &ev_file->event_list, 26778c2ecf20Sopenharmony_ci list) { 26788c2ecf20Sopenharmony_ci list_del(&entry->list); 26798c2ecf20Sopenharmony_ci kfree(entry); 26808c2ecf20Sopenharmony_ci } 26818c2ecf20Sopenharmony_ci } 26828c2ecf20Sopenharmony_ci 26838c2ecf20Sopenharmony_ci spin_unlock_irq(&ev_file->lock); 26848c2ecf20Sopenharmony_ci wake_up_interruptible(&ev_file->poll_wait); 26858c2ecf20Sopenharmony_ci 26868c2ecf20Sopenharmony_ci mutex_lock(&dev->devx_event_table.event_xa_lock); 26878c2ecf20Sopenharmony_ci /* delete the subscriptions which are related to this FD */ 26888c2ecf20Sopenharmony_ci list_for_each_entry_safe(event_sub, event_sub_tmp, 26898c2ecf20Sopenharmony_ci &ev_file->subscribed_events_list, file_list) { 26908c2ecf20Sopenharmony_ci devx_cleanup_subscription(dev, event_sub); 26918c2ecf20Sopenharmony_ci list_del_rcu(&event_sub->file_list); 26928c2ecf20Sopenharmony_ci /* subscription may not be used by the read API any more */ 26938c2ecf20Sopenharmony_ci call_rcu(&event_sub->rcu, devx_free_subscription); 26948c2ecf20Sopenharmony_ci } 26958c2ecf20Sopenharmony_ci mutex_unlock(&dev->devx_event_table.event_xa_lock); 26968c2ecf20Sopenharmony_ci 26978c2ecf20Sopenharmony_ci put_device(&dev->ib_dev.dev); 26988c2ecf20Sopenharmony_ci return 0; 26998c2ecf20Sopenharmony_ci}; 27008c2ecf20Sopenharmony_ci 27018c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 27028c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_UMEM_REG, 27038c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE, 27048c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_UMEM, 27058c2ecf20Sopenharmony_ci UVERBS_ACCESS_NEW, 27068c2ecf20Sopenharmony_ci UA_MANDATORY), 27078c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR, 27088c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u64), 27098c2ecf20Sopenharmony_ci UA_MANDATORY), 27108c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_LEN, 27118c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u64), 27128c2ecf20Sopenharmony_ci UA_MANDATORY), 27138c2ecf20Sopenharmony_ci UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, 27148c2ecf20Sopenharmony_ci enum ib_access_flags), 27158c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, 27168c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u32), 27178c2ecf20Sopenharmony_ci UA_MANDATORY)); 27188c2ecf20Sopenharmony_ci 27198c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD_DESTROY( 27208c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_UMEM_DEREG, 27218c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE, 27228c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_UMEM, 27238c2ecf20Sopenharmony_ci UVERBS_ACCESS_DESTROY, 27248c2ecf20Sopenharmony_ci UA_MANDATORY)); 27258c2ecf20Sopenharmony_ci 27268c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 27278c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_QUERY_EQN, 27288c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC, 27298c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u32), 27308c2ecf20Sopenharmony_ci UA_MANDATORY), 27318c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN, 27328c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u32), 27338c2ecf20Sopenharmony_ci UA_MANDATORY)); 27348c2ecf20Sopenharmony_ci 27358c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 27368c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_QUERY_UAR, 27378c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX, 27388c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u32), 27398c2ecf20Sopenharmony_ci UA_MANDATORY), 27408c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, 27418c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u32), 27428c2ecf20Sopenharmony_ci UA_MANDATORY)); 27438c2ecf20Sopenharmony_ci 27448c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 27458c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_OTHER, 27468c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN( 27478c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OTHER_CMD_IN, 27488c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 27498c2ecf20Sopenharmony_ci UA_MANDATORY, 27508c2ecf20Sopenharmony_ci UA_ALLOC_AND_COPY), 27518c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_OUT( 27528c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, 27538c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 27548c2ecf20Sopenharmony_ci UA_MANDATORY)); 27558c2ecf20Sopenharmony_ci 27568c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 27578c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_OBJ_CREATE, 27588c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE, 27598c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_OBJ, 27608c2ecf20Sopenharmony_ci UVERBS_ACCESS_NEW, 27618c2ecf20Sopenharmony_ci UA_MANDATORY), 27628c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN( 27638c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN, 27648c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 27658c2ecf20Sopenharmony_ci UA_MANDATORY, 27668c2ecf20Sopenharmony_ci UA_ALLOC_AND_COPY), 27678c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_OUT( 27688c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, 27698c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 27708c2ecf20Sopenharmony_ci UA_MANDATORY)); 27718c2ecf20Sopenharmony_ci 27728c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD_DESTROY( 27738c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_OBJ_DESTROY, 27748c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE, 27758c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_OBJ, 27768c2ecf20Sopenharmony_ci UVERBS_ACCESS_DESTROY, 27778c2ecf20Sopenharmony_ci UA_MANDATORY)); 27788c2ecf20Sopenharmony_ci 27798c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 27808c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_OBJ_MODIFY, 27818c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE, 27828c2ecf20Sopenharmony_ci UVERBS_IDR_ANY_OBJECT, 27838c2ecf20Sopenharmony_ci UVERBS_ACCESS_WRITE, 27848c2ecf20Sopenharmony_ci UA_MANDATORY), 27858c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN( 27868c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, 27878c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 27888c2ecf20Sopenharmony_ci UA_MANDATORY, 27898c2ecf20Sopenharmony_ci UA_ALLOC_AND_COPY), 27908c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_OUT( 27918c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, 27928c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 27938c2ecf20Sopenharmony_ci UA_MANDATORY)); 27948c2ecf20Sopenharmony_ci 27958c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 27968c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_OBJ_QUERY, 27978c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE, 27988c2ecf20Sopenharmony_ci UVERBS_IDR_ANY_OBJECT, 27998c2ecf20Sopenharmony_ci UVERBS_ACCESS_READ, 28008c2ecf20Sopenharmony_ci UA_MANDATORY), 28018c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN( 28028c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, 28038c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 28048c2ecf20Sopenharmony_ci UA_MANDATORY, 28058c2ecf20Sopenharmony_ci UA_ALLOC_AND_COPY), 28068c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_OUT( 28078c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, 28088c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)), 28098c2ecf20Sopenharmony_ci UA_MANDATORY)); 28108c2ecf20Sopenharmony_ci 28118c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 28128c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY, 28138c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE, 28148c2ecf20Sopenharmony_ci UVERBS_IDR_ANY_OBJECT, 28158c2ecf20Sopenharmony_ci UVERBS_ACCESS_READ, 28168c2ecf20Sopenharmony_ci UA_MANDATORY), 28178c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN( 28188c2ecf20Sopenharmony_ci MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, 28198c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)), 28208c2ecf20Sopenharmony_ci UA_MANDATORY, 28218c2ecf20Sopenharmony_ci UA_ALLOC_AND_COPY), 28228c2ecf20Sopenharmony_ci UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_OUT_LEN, 28238c2ecf20Sopenharmony_ci u16, UA_MANDATORY), 28248c2ecf20Sopenharmony_ci UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_FD, 28258c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 28268c2ecf20Sopenharmony_ci UVERBS_ACCESS_READ, 28278c2ecf20Sopenharmony_ci UA_MANDATORY), 28288c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_WR_ID, 28298c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u64), 28308c2ecf20Sopenharmony_ci UA_MANDATORY)); 28318c2ecf20Sopenharmony_ci 28328c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 28338c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_SUBSCRIBE_EVENT, 28348c2ecf20Sopenharmony_ci UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_FD_HANDLE, 28358c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_EVENT_FD, 28368c2ecf20Sopenharmony_ci UVERBS_ACCESS_READ, 28378c2ecf20Sopenharmony_ci UA_MANDATORY), 28388c2ecf20Sopenharmony_ci UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_OBJ_HANDLE, 28398c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_OBJ, 28408c2ecf20Sopenharmony_ci UVERBS_ACCESS_READ, 28418c2ecf20Sopenharmony_ci UA_OPTIONAL), 28428c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_TYPE_NUM_LIST, 28438c2ecf20Sopenharmony_ci UVERBS_ATTR_MIN_SIZE(sizeof(u16)), 28448c2ecf20Sopenharmony_ci UA_MANDATORY, 28458c2ecf20Sopenharmony_ci UA_ALLOC_AND_COPY), 28468c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_COOKIE, 28478c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u64), 28488c2ecf20Sopenharmony_ci UA_OPTIONAL), 28498c2ecf20Sopenharmony_ci UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_SUBSCRIBE_EVENT_FD_NUM, 28508c2ecf20Sopenharmony_ci UVERBS_ATTR_TYPE(u32), 28518c2ecf20Sopenharmony_ci UA_OPTIONAL)); 28528c2ecf20Sopenharmony_ci 28538c2ecf20Sopenharmony_ciDECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX, 28548c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER), 28558c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR), 28568c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_EQN), 28578c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_SUBSCRIBE_EVENT)); 28588c2ecf20Sopenharmony_ci 28598c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ, 28608c2ecf20Sopenharmony_ci UVERBS_TYPE_ALLOC_IDR(devx_obj_cleanup), 28618c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE), 28628c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY), 28638c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY), 28648c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY), 28658c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY)); 28668c2ecf20Sopenharmony_ci 28678c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM, 28688c2ecf20Sopenharmony_ci UVERBS_TYPE_ALLOC_IDR(devx_umem_cleanup), 28698c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG), 28708c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG)); 28718c2ecf20Sopenharmony_ci 28728c2ecf20Sopenharmony_ci 28738c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 28748c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC, 28758c2ecf20Sopenharmony_ci UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_ASYNC_CMD_FD_ALLOC_HANDLE, 28768c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 28778c2ecf20Sopenharmony_ci UVERBS_ACCESS_NEW, 28788c2ecf20Sopenharmony_ci UA_MANDATORY)); 28798c2ecf20Sopenharmony_ci 28808c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_OBJECT( 28818c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 28828c2ecf20Sopenharmony_ci UVERBS_TYPE_ALLOC_FD(sizeof(struct devx_async_cmd_event_file), 28838c2ecf20Sopenharmony_ci devx_async_cmd_event_destroy_uobj, 28848c2ecf20Sopenharmony_ci &devx_async_cmd_event_fops, "[devx_async_cmd]", 28858c2ecf20Sopenharmony_ci O_RDONLY), 28868c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC)); 28878c2ecf20Sopenharmony_ci 28888c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_METHOD( 28898c2ecf20Sopenharmony_ci MLX5_IB_METHOD_DEVX_ASYNC_EVENT_FD_ALLOC, 28908c2ecf20Sopenharmony_ci UVERBS_ATTR_FD(MLX5_IB_ATTR_DEVX_ASYNC_EVENT_FD_ALLOC_HANDLE, 28918c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_EVENT_FD, 28928c2ecf20Sopenharmony_ci UVERBS_ACCESS_NEW, 28938c2ecf20Sopenharmony_ci UA_MANDATORY), 28948c2ecf20Sopenharmony_ci UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_DEVX_ASYNC_EVENT_FD_ALLOC_FLAGS, 28958c2ecf20Sopenharmony_ci enum mlx5_ib_uapi_devx_create_event_channel_flags, 28968c2ecf20Sopenharmony_ci UA_MANDATORY)); 28978c2ecf20Sopenharmony_ci 28988c2ecf20Sopenharmony_ciDECLARE_UVERBS_NAMED_OBJECT( 28998c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_EVENT_FD, 29008c2ecf20Sopenharmony_ci UVERBS_TYPE_ALLOC_FD(sizeof(struct devx_async_event_file), 29018c2ecf20Sopenharmony_ci devx_async_event_destroy_uobj, 29028c2ecf20Sopenharmony_ci &devx_async_event_fops, "[devx_async_event]", 29038c2ecf20Sopenharmony_ci O_RDONLY), 29048c2ecf20Sopenharmony_ci &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_ASYNC_EVENT_FD_ALLOC)); 29058c2ecf20Sopenharmony_ci 29068c2ecf20Sopenharmony_cistatic bool devx_is_supported(struct ib_device *device) 29078c2ecf20Sopenharmony_ci{ 29088c2ecf20Sopenharmony_ci struct mlx5_ib_dev *dev = to_mdev(device); 29098c2ecf20Sopenharmony_ci 29108c2ecf20Sopenharmony_ci return MLX5_CAP_GEN(dev->mdev, log_max_uctx); 29118c2ecf20Sopenharmony_ci} 29128c2ecf20Sopenharmony_ci 29138c2ecf20Sopenharmony_ciconst struct uapi_definition mlx5_ib_devx_defs[] = { 29148c2ecf20Sopenharmony_ci UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 29158c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX, 29168c2ecf20Sopenharmony_ci UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 29178c2ecf20Sopenharmony_ci UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 29188c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_OBJ, 29198c2ecf20Sopenharmony_ci UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 29208c2ecf20Sopenharmony_ci UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 29218c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_UMEM, 29228c2ecf20Sopenharmony_ci UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 29238c2ecf20Sopenharmony_ci UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 29248c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD, 29258c2ecf20Sopenharmony_ci UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 29268c2ecf20Sopenharmony_ci UAPI_DEF_CHAIN_OBJ_TREE_NAMED( 29278c2ecf20Sopenharmony_ci MLX5_IB_OBJECT_DEVX_ASYNC_EVENT_FD, 29288c2ecf20Sopenharmony_ci UAPI_DEF_IS_OBJ_SUPPORTED(devx_is_supported)), 29298c2ecf20Sopenharmony_ci {}, 29308c2ecf20Sopenharmony_ci}; 2931