|
13 | 13 | #include <linux/mlx5/fs.h>
|
14 | 14 | #include "mlx5_ib.h"
|
15 | 15 |
|
| 16 | +#define UVERBS_MODULE_NAME mlx5_ib |
| 17 | +#include <rdma/uverbs_named_ioctl.h> |
| 18 | + |
| 19 | +static struct mlx5_ib_ucontext *devx_ufile2uctx(struct ib_uverbs_file *file) |
| 20 | +{ |
| 21 | + return to_mucontext(ib_uverbs_get_ucontext(file)); |
| 22 | +} |
| 23 | + |
16 | 24 | int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, struct mlx5_ib_ucontext *context)
|
17 | 25 | {
|
18 | 26 | u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {0};
|
@@ -56,3 +64,82 @@ void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev,
|
56 | 64 |
|
57 | 65 | mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
|
58 | 66 | }
|
| 67 | + |
| 68 | +static bool devx_is_general_cmd(void *in) |
| 69 | +{ |
| 70 | + u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); |
| 71 | + |
| 72 | + switch (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: |
| 82 | + case MLX5_CMD_OP_NOP: |
| 83 | + case MLX5_CMD_OP_QUERY_CONG_STATUS: |
| 84 | + case MLX5_CMD_OP_QUERY_CONG_PARAMS: |
| 85 | + case MLX5_CMD_OP_QUERY_CONG_STATISTICS: |
| 86 | + return true; |
| 87 | + default: |
| 88 | + return false; |
| 89 | + } |
| 90 | +} |
| 91 | + |
| 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) |
| 95 | +{ |
| 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); |
| 101 | + void *cmd_out; |
| 102 | + int err; |
| 103 | + |
| 104 | + if (!c->devx_uid) |
| 105 | + return -EPERM; |
| 106 | + |
| 107 | + /* Only white list of some general HCA commands are allowed for this method. */ |
| 108 | + if (!devx_is_general_cmd(cmd_in)) |
| 109 | + return -EINVAL; |
| 110 | + |
| 111 | + cmd_out = kvzalloc(cmd_out_len, GFP_KERNEL); |
| 112 | + if (!cmd_out) |
| 113 | + return -ENOMEM; |
| 114 | + |
| 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); |
| 119 | + if (err) |
| 120 | + goto other_cmd_free; |
| 121 | + |
| 122 | + err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, cmd_out, cmd_out_len); |
| 123 | + |
| 124 | +other_cmd_free: |
| 125 | + kvfree(cmd_out); |
| 126 | + return err; |
| 127 | +} |
| 128 | + |
| 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)) |
| 139 | +); |
| 140 | + |
| 141 | +static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX, |
| 142 | + &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER)); |
| 143 | + |
| 144 | +static DECLARE_UVERBS_OBJECT_TREE(devx_objects, |
| 145 | + &UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX)); |
0 commit comments