From c2a939fda468bb5c4144a64fd2b9cbdad323bf68 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Sun, 25 Nov 2018 20:58:35 +0200 Subject: [PATCH] RDMA/uverbs: Use uverbs_attr_bundle to pass ucore for write/write_ex This creates a consistent way to access the two core buffers across write and write_ex handlers. Remove the open coded ucore conversion in the write/ex compatibility handlers. Signed-off-by: Jason Gunthorpe Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford --- drivers/infiniband/core/uverbs_cmd.c | 53 +++++++++------------------ drivers/infiniband/core/uverbs_main.c | 23 ++++++------ include/rdma/uverbs_ioctl.h | 1 + 3 files changed, 31 insertions(+), 46 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 5708abc0e4d4..0dd69133096d 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -891,13 +891,11 @@ static int ib_uverbs_create_comp_channel(struct uverbs_attr_bundle *attrs, } static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs, - struct ib_udata *ucore, struct ib_uverbs_ex_create_cq *cmd, size_t cmd_sz, int (*cb)(struct uverbs_attr_bundle *attrs, struct ib_ucq_object *obj, struct ib_uverbs_ex_create_cq_resp *resp, - struct ib_udata *ucore, void *context), void *context) { @@ -962,7 +960,7 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs, cq->res.type = RDMA_RESTRACK_CQ; rdma_restrack_add(&cq->res); - ret = cb(attrs, obj, &resp, ucore, context); + ret = cb(attrs, obj, &resp, context); if (ret) goto err_cb; @@ -987,9 +985,9 @@ err: static int ib_uverbs_create_cq_cb(struct uverbs_attr_bundle *attrs, struct ib_ucq_object *obj, struct ib_uverbs_ex_create_cq_resp *resp, - struct ib_udata *ucore, void *context) + void *context) { - if (ib_copy_to_udata(ucore, &resp->base, sizeof(resp->base))) + if (ib_copy_to_udata(&attrs->ucore, &resp->base, sizeof(resp->base))) return -EFAULT; return 0; @@ -1000,23 +998,18 @@ static int ib_uverbs_create_cq(struct uverbs_attr_bundle *attrs, { struct ib_uverbs_create_cq cmd; struct ib_uverbs_ex_create_cq cmd_ex; - struct ib_uverbs_create_cq_resp resp; - struct ib_udata ucore; struct ib_ucq_object *obj; if (copy_from_user(&cmd, buf, sizeof(cmd))) return -EFAULT; - ib_uverbs_init_udata(&ucore, buf, u64_to_user_ptr(cmd.response), - sizeof(cmd), sizeof(resp)); - memset(&cmd_ex, 0, sizeof(cmd_ex)); cmd_ex.user_handle = cmd.user_handle; cmd_ex.cqe = cmd.cqe; cmd_ex.comp_vector = cmd.comp_vector; cmd_ex.comp_channel = cmd.comp_channel; - obj = create_cq(attrs, &ucore, &cmd_ex, + obj = create_cq(attrs, &cmd_ex, offsetof(typeof(cmd_ex), comp_channel) + sizeof(cmd.comp_channel), ib_uverbs_create_cq_cb, NULL); @@ -1026,9 +1019,9 @@ static int ib_uverbs_create_cq(struct uverbs_attr_bundle *attrs, static int ib_uverbs_ex_create_cq_cb(struct uverbs_attr_bundle *attrs, struct ib_ucq_object *obj, struct ib_uverbs_ex_create_cq_resp *resp, - struct ib_udata *ucore, void *context) + void *context) { - if (ib_copy_to_udata(ucore, resp, resp->response_length)) + if (ib_copy_to_udata(&attrs->ucore, resp, resp->response_length)) return -EFAULT; return 0; @@ -1059,7 +1052,7 @@ static int ib_uverbs_ex_create_cq(struct uverbs_attr_bundle *attrs, sizeof(resp.response_length))) return -ENOSPC; - obj = create_cq(attrs, ucore, &cmd, min(ucore->inlen, sizeof(cmd)), + obj = create_cq(attrs, &cmd, min(ucore->inlen, sizeof(cmd)), ib_uverbs_ex_create_cq_cb, NULL); return PTR_ERR_OR_ZERO(obj); @@ -1144,7 +1137,7 @@ static int ib_uverbs_poll_cq(struct uverbs_attr_bundle *attrs, return -EINVAL; /* we copy a struct ib_uverbs_poll_cq_resp to user space */ - header_ptr = u64_to_user_ptr(cmd.response); + header_ptr = attrs->ucore.outbuf; data_ptr = header_ptr + sizeof resp; memset(&resp, 0, sizeof resp); @@ -1226,12 +1219,9 @@ static int ib_uverbs_destroy_cq(struct uverbs_attr_bundle *attrs, } static int create_qp(struct uverbs_attr_bundle *attrs, - struct ib_udata *ucore, - struct ib_uverbs_ex_create_qp *cmd, - size_t cmd_sz, + struct ib_uverbs_ex_create_qp *cmd, size_t cmd_sz, int (*cb)(struct uverbs_attr_bundle *attrs, - struct ib_uverbs_ex_create_qp_resp *resp, - struct ib_udata *udata), + struct ib_uverbs_ex_create_qp_resp *resp), void *context) { struct ib_uqp_object *obj; @@ -1276,7 +1266,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs, } if (cmd_sz > sizeof(*cmd) && - !ib_is_udata_cleared(ucore, sizeof(*cmd), + !ib_is_udata_cleared(&attrs->ucore, sizeof(*cmd), cmd_sz - sizeof(*cmd))) { ret = -EOPNOTSUPP; goto err_put; @@ -1456,7 +1446,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs, resp.response_length = offsetof(typeof(resp), response_length) + sizeof(resp.response_length); - ret = cb(attrs, &resp, ucore); + ret = cb(attrs, &resp); if (ret) goto err_cb; @@ -1501,10 +1491,9 @@ err_put: } static int ib_uverbs_create_qp_cb(struct uverbs_attr_bundle *attrs, - struct ib_uverbs_ex_create_qp_resp *resp, - struct ib_udata *ucore) + struct ib_uverbs_ex_create_qp_resp *resp) { - if (ib_copy_to_udata(ucore, &resp->base, sizeof(resp->base))) + if (ib_copy_to_udata(&attrs->ucore, &resp->base, sizeof(resp->base))) return -EFAULT; return 0; @@ -1515,16 +1504,11 @@ static int ib_uverbs_create_qp(struct uverbs_attr_bundle *attrs, { struct ib_uverbs_create_qp cmd; struct ib_uverbs_ex_create_qp cmd_ex; - struct ib_udata ucore; - ssize_t resp_size = sizeof(struct ib_uverbs_create_qp_resp); int err; if (copy_from_user(&cmd, buf, sizeof(cmd))) return -EFAULT; - ib_uverbs_init_udata(&ucore, buf, u64_to_user_ptr(cmd.response), - sizeof(cmd), resp_size); - memset(&cmd_ex, 0, sizeof(cmd_ex)); cmd_ex.user_handle = cmd.user_handle; cmd_ex.pd_handle = cmd.pd_handle; @@ -1540,7 +1524,7 @@ static int ib_uverbs_create_qp(struct uverbs_attr_bundle *attrs, cmd_ex.qp_type = cmd.qp_type; cmd_ex.is_srq = cmd.is_srq; - err = create_qp(attrs, &ucore, &cmd_ex, + err = create_qp(attrs, &cmd_ex, offsetof(typeof(cmd_ex), is_srq) + sizeof(cmd.is_srq), ib_uverbs_create_qp_cb, NULL); @@ -1551,10 +1535,9 @@ static int ib_uverbs_create_qp(struct uverbs_attr_bundle *attrs, } static int ib_uverbs_ex_create_qp_cb(struct uverbs_attr_bundle *attrs, - struct ib_uverbs_ex_create_qp_resp *resp, - struct ib_udata *ucore) + struct ib_uverbs_ex_create_qp_resp *resp) { - if (ib_copy_to_udata(ucore, resp, resp->response_length)) + if (ib_copy_to_udata(&attrs->ucore, resp, resp->response_length)) return -EFAULT; return 0; @@ -1585,7 +1568,7 @@ static int ib_uverbs_ex_create_qp(struct uverbs_attr_bundle *attrs, sizeof(resp.response_length))) return -ENOSPC; - err = create_qp(attrs, ucore, &cmd, + err = create_qp(attrs, &cmd, min(ucore->inlen, sizeof(cmd)), ib_uverbs_ex_create_qp_cb, NULL); diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index be049546cee2..762a6acbff80 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -695,6 +695,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, if (!method_elm->is_ex) { size_t in_len = hdr.in_words * 4 - sizeof(hdr); size_t out_len = hdr.out_words * 4; + u64 response = 0; if (method_elm->has_udata) { bundle.driver_udata.inlen = @@ -710,8 +711,6 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, } if (method_elm->has_resp) { - u64 response; - /* * The macros check that if has_resp is set * then the command request structure starts @@ -737,23 +736,25 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, bundle.driver_udata.outbuf = NULL; } + ib_uverbs_init_udata_buf_or_null( + &bundle.ucore, buf, u64_to_user_ptr(response), + in_len, out_len); + ret = method_elm->handler(&bundle, buf, in_len, out_len); } else { - struct ib_udata ucore; - buf += sizeof(ex_hdr); - ib_uverbs_init_udata_buf_or_null(&ucore, buf, + ib_uverbs_init_udata_buf_or_null(&bundle.ucore, buf, u64_to_user_ptr(ex_hdr.response), hdr.in_words * 8, hdr.out_words * 8); - ib_uverbs_init_udata_buf_or_null(&bundle.driver_udata, - buf + ucore.inlen, - u64_to_user_ptr(ex_hdr.response) + ucore.outlen, - ex_hdr.provider_in_words * 8, - ex_hdr.provider_out_words * 8); + ib_uverbs_init_udata_buf_or_null( + &bundle.driver_udata, buf + bundle.ucore.inlen, + u64_to_user_ptr(ex_hdr.response) + bundle.ucore.outlen, + ex_hdr.provider_in_words * 8, + ex_hdr.provider_out_words * 8); - ret = method_elm->handler_ex(&bundle, &ucore); + ret = method_elm->handler_ex(&bundle, &bundle.ucore); } out_unlock: diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h index 8fc87079c2b8..9486a525afc1 100644 --- a/include/rdma/uverbs_ioctl.h +++ b/include/rdma/uverbs_ioctl.h @@ -647,6 +647,7 @@ struct uverbs_attr { struct uverbs_attr_bundle { struct ib_udata driver_udata; + struct ib_udata ucore; struct ib_uverbs_file *ufile; DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN); struct uverbs_attr attrs[];