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