From: Haggai Eran <haggaie-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
To: Eran Ben Elisha <eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>,
Doug Ledford <dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Or Gerlitz <ogerlitz-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>,
Christoph Lameter <cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>
Subject: Re: [PATCH v2 for-next 1/7] IB/core: Extend ib_uverbs_create_qp
Date: Wed, 21 Oct 2015 11:34:10 +0300 [thread overview]
Message-ID: <56274E02.7010002@mellanox.com> (raw)
In-Reply-To: <1444909482-17113-2-git-send-email-eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
On 15/10/2015 14:44, Eran Ben Elisha wrote:
> ib_uverbs_ex_create_qp follows the extension verbs
> mechanism. New features (for example, QP creation flags
> field which is added in a downstream patch) could used
> via user-space libraries without breaking the ABI.
>
> Signed-off-by: Eran Ben Elisha <eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> ---
> diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> index be4cb9f..e795d59 100644
> --- a/drivers/infiniband/core/uverbs_cmd.c
> +++ b/drivers/infiniband/core/uverbs_cmd.c
> @@ -1741,66 +1741,65 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
> return in_len;
> }
>
> -ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
> - struct ib_device *ib_dev,
> - const char __user *buf, int in_len,
> - int out_len)
> -{
> - struct ib_uverbs_create_qp cmd;
> - struct ib_uverbs_create_qp_resp resp;
> - struct ib_udata udata;
> - struct ib_uqp_object *obj;
> - struct ib_device *device;
> - struct ib_pd *pd = NULL;
> - struct ib_xrcd *xrcd = NULL;
> - struct ib_uobject *uninitialized_var(xrcd_uobj);
> - struct ib_cq *scq = NULL, *rcq = NULL;
> - struct ib_srq *srq = NULL;
> - struct ib_qp *qp;
> - struct ib_qp_init_attr attr;
> - int ret;
> -
> - if (out_len < sizeof resp)
> - return -ENOSPC;
> -
> - if (copy_from_user(&cmd, buf, sizeof cmd))
> - return -EFAULT;
> +static int create_qp(struct ib_uverbs_file *file,
> + struct ib_udata *ucore,
> + struct ib_udata *uhw,
> + struct ib_uverbs_ex_create_qp *cmd,
> + size_t cmd_sz,
> + int (*cb)(struct ib_uverbs_file *file,
> + struct ib_uverbs_ex_create_qp_resp *resp,
> + struct ib_udata *udata),
> + void *context)
> +{
> + struct ib_uqp_object *obj;
> + struct ib_device *device;
> + struct ib_pd *pd = NULL;
> + struct ib_xrcd *xrcd = NULL;
> + struct ib_uobject *uninitialized_var(xrcd_uobj);
> + struct ib_cq *scq = NULL, *rcq = NULL;
> + struct ib_srq *srq = NULL;
> + struct ib_qp *qp;
> + char *buf;
> + struct ib_qp_init_attr attr;
> + struct ib_uverbs_ex_create_qp_resp resp;
> + int ret;
>
> - if (cmd.qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW))
> + if (cmd->qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW))
> return -EPERM;
>
> - INIT_UDATA(&udata, buf + sizeof cmd,
> - (unsigned long) cmd.response + sizeof resp,
> - in_len - sizeof cmd, out_len - sizeof resp);
> -
> obj = kzalloc(sizeof *obj, GFP_KERNEL);
> if (!obj)
> return -ENOMEM;
>
> - init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_class);
> + init_uobj(&obj->uevent.uobject, cmd->user_handle, file->ucontext,
> + &qp_lock_class);
> down_write(&obj->uevent.uobject.mutex);
>
> - if (cmd.qp_type == IB_QPT_XRC_TGT) {
> - xrcd = idr_read_xrcd(cmd.pd_handle, file->ucontext, &xrcd_uobj);
> + if (cmd->qp_type == IB_QPT_XRC_TGT) {
> + xrcd = idr_read_xrcd(cmd->pd_handle, file->ucontext,
> + &xrcd_uobj);
> if (!xrcd) {
> ret = -EINVAL;
> goto err_put;
> }
> device = xrcd->device;
> } else {
> - if (cmd.qp_type == IB_QPT_XRC_INI) {
> - cmd.max_recv_wr = cmd.max_recv_sge = 0;
> + if (cmd->qp_type == IB_QPT_XRC_INI) {
> + cmd->max_recv_wr = 0;
> + cmd->max_recv_sge = 0;
> } else {
> - if (cmd.is_srq) {
> - srq = idr_read_srq(cmd.srq_handle, file->ucontext);
> + if (cmd->is_srq) {
> + srq = idr_read_srq(cmd->srq_handle,
> + file->ucontext);
> if (!srq || srq->srq_type != IB_SRQT_BASIC) {
> ret = -EINVAL;
> goto err_put;
> }
> }
>
> - if (cmd.recv_cq_handle != cmd.send_cq_handle) {
> - rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext, 0);
> + if (cmd->recv_cq_handle != cmd->send_cq_handle) {
> + rcq = idr_read_cq(cmd->recv_cq_handle,
> + file->ucontext, 0);
> if (!rcq) {
> ret = -EINVAL;
> goto err_put;
> @@ -1808,9 +1807,9 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
> }
> }
>
> - scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, !!rcq);
> + scq = idr_read_cq(cmd->send_cq_handle, file->ucontext, !!rcq);
> rcq = rcq ?: scq;
> - pd = idr_read_pd(cmd.pd_handle, file->ucontext);
> + pd = idr_read_pd(cmd->pd_handle, file->ucontext);
> if (!pd || !scq) {
> ret = -EINVAL;
> goto err_put;
> @@ -1825,31 +1824,54 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
> attr.recv_cq = rcq;
> attr.srq = srq;
> attr.xrcd = xrcd;
> - attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
> - attr.qp_type = cmd.qp_type;
> + attr.sq_sig_type = cmd->sq_sig_all ? IB_SIGNAL_ALL_WR :
> + IB_SIGNAL_REQ_WR;
> + attr.qp_type = cmd->qp_type;
> attr.create_flags = 0;
>
> - attr.cap.max_send_wr = cmd.max_send_wr;
> - attr.cap.max_recv_wr = cmd.max_recv_wr;
> - attr.cap.max_send_sge = cmd.max_send_sge;
> - attr.cap.max_recv_sge = cmd.max_recv_sge;
> - attr.cap.max_inline_data = cmd.max_inline_data;
> + attr.cap.max_send_wr = cmd->max_send_wr;
> + attr.cap.max_recv_wr = cmd->max_recv_wr;
> + attr.cap.max_send_sge = cmd->max_send_sge;
> + attr.cap.max_recv_sge = cmd->max_recv_sge;
> + attr.cap.max_inline_data = cmd->max_inline_data;
>
> obj->uevent.events_reported = 0;
> INIT_LIST_HEAD(&obj->uevent.event_list);
> INIT_LIST_HEAD(&obj->mcast_list);
>
> - if (cmd.qp_type == IB_QPT_XRC_TGT)
> + if (cmd_sz >= offsetof(typeof(*cmd), create_flags) +
> + sizeof(cmd->create_flags))
> + attr.create_flags = cmd->create_flags;
> +
> + if (attr.create_flags) {
> + ret = -EINVAL;
> + goto err_put;
> + }
> +
> + if (cmd->comp_mask) {
Do you need this check in addition to the check in ib_uverbs_ex_create_qp()?
> + ret = -EINVAL;
> + goto err_put;
> + }
> +
> + buf = (void *)cmd + sizeof(*cmd);
> + if (cmd_sz > sizeof(*cmd))
> + if (!(buf[0] == 0 && !memcmp(buf, buf + 1,
> + cmd_sz - sizeof(*cmd) - 1))) {
> + ret = -EINVAL;
> + goto err_put;
> + }
> +
> + if (cmd->qp_type == IB_QPT_XRC_TGT)
> qp = ib_create_qp(pd, &attr);
> else
> - qp = device->create_qp(pd, &attr, &udata);
> + qp = device->create_qp(pd, &attr, uhw);
>
> if (IS_ERR(qp)) {
> ret = PTR_ERR(qp);
> goto err_put;
> }
>
> - if (cmd.qp_type != IB_QPT_XRC_TGT) {
> + if (cmd->qp_type != IB_QPT_XRC_TGT) {
> qp->real_qp = qp;
> qp->device = device;
> qp->pd = pd;
> @@ -1875,19 +1897,20 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
> goto err_destroy;
>
> memset(&resp, 0, sizeof resp);
> - resp.qpn = qp->qp_num;
> - resp.qp_handle = obj->uevent.uobject.id;
> - resp.max_recv_sge = attr.cap.max_recv_sge;
> - resp.max_send_sge = attr.cap.max_send_sge;
> - resp.max_recv_wr = attr.cap.max_recv_wr;
> - resp.max_send_wr = attr.cap.max_send_wr;
> - resp.max_inline_data = attr.cap.max_inline_data;
> + resp.base.qpn = qp->qp_num;
> + resp.base.qp_handle = obj->uevent.uobject.id;
> + resp.base.max_recv_sge = attr.cap.max_recv_sge;
> + resp.base.max_send_sge = attr.cap.max_send_sge;
> + resp.base.max_recv_wr = attr.cap.max_recv_wr;
> + resp.base.max_send_wr = attr.cap.max_send_wr;
> + resp.base.max_inline_data = attr.cap.max_inline_data;
>
> - if (copy_to_user((void __user *) (unsigned long) cmd.response,
> - &resp, sizeof resp)) {
> - ret = -EFAULT;
> - goto err_copy;
> - }
> + resp.response_length = offsetof(typeof(resp), response_length) +
> + sizeof(resp.response_length);
> +
> + ret = cb(file, &resp, ucore);
> + if (ret)
> + goto err_cb;
>
> if (xrcd) {
> obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
> @@ -1913,9 +1936,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
>
> up_write(&obj->uevent.uobject.mutex);
>
> - return in_len;
> -
> -err_copy:
> + return 0;
> +err_cb:
> idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject);
>
> err_destroy:
> @@ -1937,6 +1959,113 @@ err_put:
> return ret;
> }
>
> +static int ib_uverbs_create_qp_cb(struct ib_uverbs_file *file,
> + struct ib_uverbs_ex_create_qp_resp *resp,
> + struct ib_udata *ucore)
> +{
> + if (ib_copy_to_udata(ucore, &resp->base, sizeof(resp->base)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
> + struct ib_device *ib_dev,
> + const char __user *buf, int in_len,
> + int out_len)
> +{
> + struct ib_uverbs_create_qp cmd;
> + struct ib_uverbs_ex_create_qp cmd_ex;
> + struct ib_udata ucore;
> + struct ib_udata uhw;
> + ssize_t resp_size = sizeof(struct ib_uverbs_create_qp_resp);
> + int err;
I would expect a check here that in_len >= sizeof(cmd). But I see the
previous code didn't have it either. Any reason adding the check would
break user-space?
> +
> + if (out_len < resp_size)
> + return -ENOSPC;
> +
> + if (copy_from_user(&cmd, buf, sizeof(cmd)))
> + return -EFAULT;
> +
> + INIT_UDATA(&ucore, buf, (unsigned long)cmd.response, sizeof(cmd),
> + resp_size);
> + INIT_UDATA(&uhw, buf + sizeof(cmd),
> + (unsigned long)cmd.response + resp_size,
> + in_len - sizeof(cmd), out_len - resp_size);
> +
> + memset(&cmd_ex, 0, sizeof(cmd_ex));
> + cmd_ex.user_handle = cmd.user_handle;
> + cmd_ex.pd_handle = cmd.pd_handle;
> + cmd_ex.send_cq_handle = cmd.send_cq_handle;
> + cmd_ex.recv_cq_handle = cmd.recv_cq_handle;
> + cmd_ex.srq_handle = cmd.srq_handle;
> + cmd_ex.max_send_wr = cmd.max_send_wr;
> + cmd_ex.max_recv_wr = cmd.max_recv_wr;
> + cmd_ex.max_send_sge = cmd.max_send_sge;
> + cmd_ex.max_recv_sge = cmd.max_recv_sge;
> + cmd_ex.max_inline_data = cmd.max_inline_data;
> + cmd_ex.sq_sig_all = cmd.sq_sig_all;
> + cmd_ex.qp_type = cmd.qp_type;
> + cmd_ex.is_srq = cmd.is_srq;
> +
> + err = create_qp(file, &ucore, &uhw, &cmd_ex,
> + offsetof(typeof(cmd_ex), is_srq) +
> + sizeof(cmd.is_srq), ib_uverbs_create_qp_cb,
> + NULL);
> +
> + if (err)
> + return err;
> +
> + return in_len;
> +}
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-10-21 8:34 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-15 11:44 [PATCH v2 for-next 0/7] Add support for multicast loopback prevention to mlx4 Eran Ben Elisha
[not found] ` <1444909482-17113-1-git-send-email-eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-10-15 11:44 ` [PATCH v2 for-next 1/7] IB/core: Extend ib_uverbs_create_qp Eran Ben Elisha
[not found] ` <1444909482-17113-2-git-send-email-eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-10-21 8:34 ` Haggai Eran [this message]
[not found] ` <56274E02.7010002-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-10-21 13:46 ` eran ben elisha
[not found] ` <CAKHjkj=k6QSKj0gMe0z5=Kjbe2e7cVCbPhkq9Z457gpvnRyitg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-10-21 14:42 ` Haggai Eran
2015-10-21 9:53 ` Sagi Grimberg
[not found] ` <56276095.6020803-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-10-21 10:04 ` Or Gerlitz
[not found] ` <56276336.7000704-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-10-21 14:09 ` Sagi Grimberg
[not found] ` <56279CA4.8040201-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-10-21 18:15 ` Or Gerlitz
[not found] ` <CAJ3xEMgWcpKbKL3jhiK2RP=H6_iY0eriirAXn1TJaSG7u8frAA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-10-21 18:21 ` Christoph Lameter
[not found] ` <alpine.DEB.2.20.1510211319520.10833-wcBtFHqTun5QOdAKl3ChDw@public.gmane.org>
2015-10-21 18:52 ` Or Gerlitz
2015-10-21 10:26 ` Haggai Eran
2015-10-15 11:44 ` [PATCH v2 for-next 2/7] IB/core: Allow setting create flags in QP init attribute Eran Ben Elisha
[not found] ` <1444909482-17113-3-git-send-email-eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-10-21 8:46 ` Haggai Eran
2015-10-15 11:44 ` [PATCH v2 for-next 3/7] net/mlx4_core: Add support for filtering multicast loopback Eran Ben Elisha
2015-10-15 11:44 ` [PATCH v2 for-next 4/7] net/mlx4_en: Implement mcast loopback prevention for ETH qps Eran Ben Elisha
2015-10-15 11:44 ` [PATCH v2 for-next 5/7] IB/mlx4: Add IB counters table Eran Ben Elisha
[not found] ` <1444909482-17113-6-git-send-email-eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-12-24 10:12 ` Sagi Grimberg
[not found] ` <567BC52B.4030801-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-12-24 10:30 ` Sagi Grimberg
2015-12-24 10:34 ` Or Gerlitz
[not found] ` <567BCA3F.7050502-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-12-24 10:42 ` Sagi Grimberg
[not found] ` <567BCBF8.30006-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-12-24 12:38 ` Or Gerlitz
[not found] ` <567BE756.9050005-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2015-12-24 14:07 ` Matan Barak
[not found] ` <CAAKD3BBsv8Qe=RZvCTOa=0kuSAqYetx4NOok_Tcp5xtUz+Ggtw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-12-24 16:09 ` Matan Barak
[not found] ` <CAAKD3BB5-hUC=0bDqxXxuag9TPqQEeMD74paHrAMOc-MsQwEow-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-12-25 14:50 ` Hal Rosenstock
[not found] ` <567D57A5.2050908-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-12-25 15:56 ` Hal Rosenstock
[not found] ` <567D674B.9050807-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-12-27 11:16 ` Matan Barak
2015-10-15 11:44 ` [PATCH v2 for-next 6/7] IB/mlx4: Add counter based implementation for QP multicast loopback block Eran Ben Elisha
2015-10-15 11:44 ` [PATCH v2 for-next 7/7] IB/mlx4: Add support for blocking multicast loopback QP creation user flag Eran Ben Elisha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56274E02.7010002@mellanox.com \
--to=haggaie-vpraknaxozvwk0htik3j/w@public.gmane.org \
--cc=cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org \
--cc=dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=eranbe-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org \
--cc=linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=ogerlitz-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).