Loading drivers/infiniband/core/ucma.c +73 −1 Original line number Diff line number Diff line Loading @@ -792,6 +792,78 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, return ret; } static int ucma_set_option_id(struct ucma_context *ctx, int optname, void *optval, size_t optlen) { int ret = 0; switch (optname) { case RDMA_OPTION_ID_TOS: if (optlen != sizeof(u8)) { ret = -EINVAL; break; } rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); break; default: ret = -ENOSYS; } return ret; } static int ucma_set_option_level(struct ucma_context *ctx, int level, int optname, void *optval, size_t optlen) { int ret; switch (level) { case RDMA_OPTION_ID: ret = ucma_set_option_id(ctx, optname, optval, optlen); break; default: ret = -ENOSYS; } return ret; } static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, int in_len, int out_len) { struct rdma_ucm_set_option cmd; struct ucma_context *ctx; void *optval; int ret; if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); optval = kmalloc(cmd.optlen, GFP_KERNEL); if (!optval) { ret = -ENOMEM; goto out1; } if (copy_from_user(optval, (void __user *) (unsigned long) cmd.optval, cmd.optlen)) { ret = -EFAULT; goto out2; } ret = ucma_set_option_level(ctx, cmd.level, cmd.optname, optval, cmd.optlen); out2: kfree(optval); out1: ucma_put_ctx(ctx); return ret; } static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, int in_len, int out_len) { Loading Loading @@ -936,7 +1008,7 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, [RDMA_USER_CM_CMD_GET_OPTION] = NULL, [RDMA_USER_CM_CMD_SET_OPTION] = NULL, [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option, [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, Loading include/rdma/rdma_user_cm.h +18 −0 Original line number Diff line number Diff line Loading @@ -212,4 +212,22 @@ struct rdma_ucm_event_resp { } param; }; /* Option levels */ enum { RDMA_OPTION_ID = 0 }; /* Option details */ enum { RDMA_OPTION_ID_TOS = 0 }; struct rdma_ucm_set_option { __u64 optval; __u32 id; __u32 level; __u32 optname; __u32 optlen; }; #endif /* RDMA_USER_CM_H */ Loading
drivers/infiniband/core/ucma.c +73 −1 Original line number Diff line number Diff line Loading @@ -792,6 +792,78 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, return ret; } static int ucma_set_option_id(struct ucma_context *ctx, int optname, void *optval, size_t optlen) { int ret = 0; switch (optname) { case RDMA_OPTION_ID_TOS: if (optlen != sizeof(u8)) { ret = -EINVAL; break; } rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); break; default: ret = -ENOSYS; } return ret; } static int ucma_set_option_level(struct ucma_context *ctx, int level, int optname, void *optval, size_t optlen) { int ret; switch (level) { case RDMA_OPTION_ID: ret = ucma_set_option_id(ctx, optname, optval, optlen); break; default: ret = -ENOSYS; } return ret; } static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, int in_len, int out_len) { struct rdma_ucm_set_option cmd; struct ucma_context *ctx; void *optval; int ret; if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; ctx = ucma_get_ctx(file, cmd.id); if (IS_ERR(ctx)) return PTR_ERR(ctx); optval = kmalloc(cmd.optlen, GFP_KERNEL); if (!optval) { ret = -ENOMEM; goto out1; } if (copy_from_user(optval, (void __user *) (unsigned long) cmd.optval, cmd.optlen)) { ret = -EFAULT; goto out2; } ret = ucma_set_option_level(ctx, cmd.level, cmd.optname, optval, cmd.optlen); out2: kfree(optval); out1: ucma_put_ctx(ctx); return ret; } static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, int in_len, int out_len) { Loading Loading @@ -936,7 +1008,7 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, [RDMA_USER_CM_CMD_GET_OPTION] = NULL, [RDMA_USER_CM_CMD_SET_OPTION] = NULL, [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option, [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, Loading
include/rdma/rdma_user_cm.h +18 −0 Original line number Diff line number Diff line Loading @@ -212,4 +212,22 @@ struct rdma_ucm_event_resp { } param; }; /* Option levels */ enum { RDMA_OPTION_ID = 0 }; /* Option details */ enum { RDMA_OPTION_ID_TOS = 0 }; struct rdma_ucm_set_option { __u64 optval; __u32 id; __u32 level; __u32 optname; __u32 optlen; }; #endif /* RDMA_USER_CM_H */