1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
3 * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
6 #include <rdma/ib_user_verbs.h>
7 #include <rdma/ib_verbs.h>
8 #include <rdma/uverbs_types.h>
9 #include <rdma/uverbs_ioctl.h>
10 #include <rdma/mlx5_user_ioctl_cmds.h>
11 #include <rdma/ib_umem.h>
12 #include <linux/mlx5/driver.h>
13 #include <linux/mlx5/fs.h>
16 #define UVERBS_MODULE_NAME mlx5_ib
17 #include <rdma/uverbs_named_ioctl.h>
19 static struct mlx5_ib_ucontext
*devx_ufile2uctx(struct ib_uverbs_file
*file
)
21 return to_mucontext(ib_uverbs_get_ucontext(file
));
24 int mlx5_ib_devx_create(struct mlx5_ib_dev
*dev
, struct mlx5_ib_ucontext
*context
)
26 u32 in
[MLX5_ST_SZ_DW(create_uctx_in
)] = {0};
27 u32 out
[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr
)] = {0};
28 u64 general_obj_types
;
33 uctx
= MLX5_ADDR_OF(create_uctx_in
, in
, uctx
);
34 hdr
= MLX5_ADDR_OF(create_uctx_in
, in
, hdr
);
36 general_obj_types
= MLX5_CAP_GEN_64(dev
->mdev
, general_obj_types
);
37 if (!(general_obj_types
& MLX5_GENERAL_OBJ_TYPES_CAP_UCTX
) ||
38 !(general_obj_types
& MLX5_GENERAL_OBJ_TYPES_CAP_UMEM
))
41 if (!capable(CAP_NET_RAW
))
44 MLX5_SET(general_obj_in_cmd_hdr
, hdr
, opcode
, MLX5_CMD_OP_CREATE_GENERAL_OBJECT
);
45 MLX5_SET(general_obj_in_cmd_hdr
, hdr
, obj_type
, MLX5_OBJ_TYPE_UCTX
);
47 err
= mlx5_cmd_exec(dev
->mdev
, in
, sizeof(in
), out
, sizeof(out
));
51 context
->devx_uid
= MLX5_GET(general_obj_out_cmd_hdr
, out
, obj_id
);
55 void mlx5_ib_devx_destroy(struct mlx5_ib_dev
*dev
,
56 struct mlx5_ib_ucontext
*context
)
58 u32 in
[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr
)] = {0};
59 u32 out
[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr
)] = {0};
61 MLX5_SET(general_obj_in_cmd_hdr
, in
, opcode
, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT
);
62 MLX5_SET(general_obj_in_cmd_hdr
, in
, obj_type
, MLX5_OBJ_TYPE_UCTX
);
63 MLX5_SET(general_obj_in_cmd_hdr
, in
, obj_id
, context
->devx_uid
);
65 mlx5_cmd_exec(dev
->mdev
, in
, sizeof(in
), out
, sizeof(out
));
68 static bool devx_is_general_cmd(void *in
)
70 u16 opcode
= MLX5_GET(general_obj_in_cmd_hdr
, in
, opcode
);
73 case MLX5_CMD_OP_QUERY_HCA_CAP
:
74 case MLX5_CMD_OP_QUERY_VPORT_STATE
:
75 case MLX5_CMD_OP_QUERY_ADAPTER
:
76 case MLX5_CMD_OP_QUERY_ISSI
:
77 case MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT
:
78 case MLX5_CMD_OP_QUERY_ROCE_ADDRESS
:
79 case MLX5_CMD_OP_QUERY_VNIC_ENV
:
80 case MLX5_CMD_OP_QUERY_VPORT_COUNTER
:
81 case MLX5_CMD_OP_GET_DROPPED_PACKET_LOG
:
83 case MLX5_CMD_OP_QUERY_CONG_STATUS
:
84 case MLX5_CMD_OP_QUERY_CONG_PARAMS
:
85 case MLX5_CMD_OP_QUERY_CONG_STATISTICS
:
92 static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER
)(struct ib_device
*ib_dev
,
93 struct ib_uverbs_file
*file
,
94 struct uverbs_attr_bundle
*attrs
)
96 struct mlx5_ib_ucontext
*c
= devx_ufile2uctx(file
);
97 struct mlx5_ib_dev
*dev
= to_mdev(ib_dev
);
98 void *cmd_in
= uverbs_attr_get_alloced_ptr(attrs
, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN
);
99 int cmd_out_len
= uverbs_attr_get_len(attrs
,
100 MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT
);
107 /* Only white list of some general HCA commands are allowed for this method. */
108 if (!devx_is_general_cmd(cmd_in
))
111 cmd_out
= kvzalloc(cmd_out_len
, GFP_KERNEL
);
115 MLX5_SET(general_obj_in_cmd_hdr
, cmd_in
, uid
, c
->devx_uid
);
116 err
= mlx5_cmd_exec(dev
->mdev
, cmd_in
,
117 uverbs_attr_get_len(attrs
, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN
),
118 cmd_out
, cmd_out_len
);
122 err
= uverbs_copy_to(attrs
, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT
, cmd_out
, cmd_out_len
);
129 static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OTHER
,
130 &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN
,
131 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr
)),
132 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY
|
133 UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO
|
134 UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY
)),
135 &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT
,
136 UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr
)),
137 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY
|
138 UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO
))
141 static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX
,
142 &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER
));
144 static DECLARE_UVERBS_OBJECT_TREE(devx_objects
,
145 &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX
));