Go treewide and consolidate all existing patterns using:

* offsetofend() and variations
* ib_is_udata_cleared()
* ib_copy_from_udata()

into a direct call to the new ib_copy_validate_udata_in().

Signed-off-by: Jason Gunthorpe <[email protected]>
---
 drivers/infiniband/hw/efa/efa_verbs.c | 47 +++---------------------
 drivers/infiniband/hw/irdma/verbs.c   | 10 +++---
 drivers/infiniband/hw/mlx4/qp.c       | 38 ++++----------------
 drivers/infiniband/hw/mlx5/qp.c       | 51 ++++++---------------------
 4 files changed, 26 insertions(+), 120 deletions(-)

diff --git a/drivers/infiniband/hw/efa/efa_verbs.c 
b/drivers/infiniband/hw/efa/efa_verbs.c
index fc498663cd372f..8d9357e2d513bb 100644
--- a/drivers/infiniband/hw/efa/efa_verbs.c
+++ b/drivers/infiniband/hw/efa/efa_verbs.c
@@ -699,29 +699,9 @@ int efa_create_qp(struct ib_qp *ibqp, struct 
ib_qp_init_attr *init_attr,
        if (err)
                goto err_out;
 
-       if (offsetofend(typeof(cmd), driver_qp_type) > udata->inlen) {
-               ibdev_dbg(&dev->ibdev,
-                         "Incompatible ABI params, no input udata\n");
-               err = -EINVAL;
+       err = ib_copy_validate_udata_in(udata, cmd, driver_qp_type);
+       if (err)
                goto err_out;
-       }
-
-       if (udata->inlen > sizeof(cmd) &&
-           !ib_is_udata_cleared(udata, sizeof(cmd),
-                                udata->inlen - sizeof(cmd))) {
-               ibdev_dbg(&dev->ibdev,
-                         "Incompatible ABI params, unknown fields in udata\n");
-               err = -EINVAL;
-               goto err_out;
-       }
-
-       err = ib_copy_from_udata(&cmd, udata,
-                                min(sizeof(cmd), udata->inlen));
-       if (err) {
-               ibdev_dbg(&dev->ibdev,
-                         "Cannot copy udata for create_qp\n");
-               goto err_out;
-       }
 
        if (cmd.comp_mask || !is_reserved_cleared(cmd.reserved_98)) {
                ibdev_dbg(&dev->ibdev,
@@ -1160,28 +1140,9 @@ int efa_create_user_cq(struct ib_cq *ibcq, const struct 
ib_cq_init_attr *attr,
                goto err_out;
        }
 
-       if (offsetofend(typeof(cmd), num_sub_cqs) > udata->inlen) {
-               ibdev_dbg(ibdev,
-                         "Incompatible ABI params, no input udata\n");
-               err = -EINVAL;
+       err = ib_copy_validate_udata_in(udata, cmd, num_sub_cqs);
+       if (err)
                goto err_out;
-       }
-
-       if (udata->inlen > sizeof(cmd) &&
-           !ib_is_udata_cleared(udata, sizeof(cmd),
-                                udata->inlen - sizeof(cmd))) {
-               ibdev_dbg(ibdev,
-                         "Incompatible ABI params, unknown fields in udata\n");
-               err = -EINVAL;
-               goto err_out;
-       }
-
-       err = ib_copy_from_udata(&cmd, udata,
-                                min(sizeof(cmd), udata->inlen));
-       if (err) {
-               ibdev_dbg(ibdev, "Cannot copy udata for create_cq\n");
-               goto err_out;
-       }
 
        if (cmd.comp_mask || !is_reserved_cleared(cmd.reserved_58)) {
                ibdev_dbg(ibdev,
diff --git a/drivers/infiniband/hw/irdma/verbs.c 
b/drivers/infiniband/hw/irdma/verbs.c
index 7251cd7a21471e..b2978632241900 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -284,7 +284,6 @@ static void irdma_alloc_push_page(struct irdma_qp *iwqp)
 static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
                                struct ib_udata *udata)
 {
-#define IRDMA_ALLOC_UCTX_MIN_REQ_LEN offsetofend(struct 
irdma_alloc_ucontext_req, rsvd8)
 #define IRDMA_ALLOC_UCTX_MIN_RESP_LEN offsetofend(struct 
irdma_alloc_ucontext_resp, rsvd)
        struct ib_device *ibdev = uctx->device;
        struct irdma_device *iwdev = to_iwdev(ibdev);
@@ -292,13 +291,14 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
        struct irdma_alloc_ucontext_resp uresp = {};
        struct irdma_ucontext *ucontext = to_ucontext(uctx);
        struct irdma_uk_attrs *uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs;
+       int ret;
 
-       if (udata->inlen < IRDMA_ALLOC_UCTX_MIN_REQ_LEN ||
-           udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN)
+       if (udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN)
                return -EINVAL;
 
-       if (ib_copy_from_udata(&req, udata, min(sizeof(req), udata->inlen)))
-               return -EINVAL;
+       ret = ib_copy_validate_udata_in(udata, req, rsvd8);
+       if (ret)
+               return ret;
 
        if (req.userspace_ver < 4 || req.userspace_ver > IRDMA_ABI_VER)
                goto ver_error;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 1cb890d3d93cea..b87a4b7949a3a0 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -710,7 +710,6 @@ static int _mlx4_ib_create_qp_rss(struct ib_pd *pd, struct 
mlx4_ib_qp *qp,
                                  struct ib_udata *udata)
 {
        struct mlx4_ib_create_qp_rss ucmd = {};
-       size_t required_cmd_sz;
        int err;
 
        if (!udata) {
@@ -721,16 +720,10 @@ static int _mlx4_ib_create_qp_rss(struct ib_pd *pd, 
struct mlx4_ib_qp *qp,
        if (udata->outlen)
                return -EOPNOTSUPP;
 
-       required_cmd_sz = offsetof(typeof(ucmd), reserved1) +
-                                       sizeof(ucmd.reserved1);
-       if (udata->inlen < required_cmd_sz) {
-               pr_debug("invalid inlen\n");
-               return -EINVAL;
-       }
-
-       if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) {
+       err = ib_copy_validate_udata_in(udata, ucmd, reserved1);
+       if (err) {
                pr_debug("copy failed\n");
-               return -EFAULT;
+               return err;
        }
 
        if (memchr_inv(ucmd.reserved, 0, sizeof(ucmd.reserved)))
@@ -739,13 +732,6 @@ static int _mlx4_ib_create_qp_rss(struct ib_pd *pd, struct 
mlx4_ib_qp *qp,
        if (ucmd.comp_mask || ucmd.reserved1)
                return -EOPNOTSUPP;
 
-       if (udata->inlen > sizeof(ucmd) &&
-           !ib_is_udata_cleared(udata, sizeof(ucmd),
-                                udata->inlen - sizeof(ucmd))) {
-               pr_debug("inlen is not supported\n");
-               return -EOPNOTSUPP;
-       }
-
        if (init_attr->qp_type != IB_QPT_RAW_PACKET) {
                pr_debug("RSS QP with unsupported QP type %d\n",
                         init_attr->qp_type);
@@ -4269,22 +4255,12 @@ int mlx4_ib_modify_wq(struct ib_wq *ibwq, struct 
ib_wq_attr *wq_attr,
 {
        struct mlx4_ib_qp *qp = to_mqp((struct ib_qp *)ibwq);
        struct mlx4_ib_modify_wq ucmd = {};
-       size_t required_cmd_sz;
        enum ib_wq_state cur_state, new_state;
-       int err = 0;
+       int err;
 
-       required_cmd_sz = offsetof(typeof(ucmd), reserved) +
-                                  sizeof(ucmd.reserved);
-       if (udata->inlen < required_cmd_sz)
-               return -EINVAL;
-
-       if (udata->inlen > sizeof(ucmd) &&
-           !ib_is_udata_cleared(udata, sizeof(ucmd),
-                                udata->inlen - sizeof(ucmd)))
-               return -EOPNOTSUPP;
-
-       if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)))
-               return -EFAULT;
+       err = ib_copy_validate_udata_in(udata, ucmd, reserved);
+       if (err)
+               return err;
 
        if (ucmd.comp_mask || ucmd.reserved)
                return -EOPNOTSUPP;
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 59f9ddb35d4620..d4d5e0d457a0b5 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -4707,17 +4707,9 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct 
ib_qp_attr *attr,
                return -ENOSYS;
 
        if (udata && udata->inlen) {
-               if (udata->inlen < offsetofend(typeof(ucmd), ece_options))
-                       return -EINVAL;
-
-               if (udata->inlen > sizeof(ucmd) &&
-                   !ib_is_udata_cleared(udata, sizeof(ucmd),
-                                        udata->inlen - sizeof(ucmd)))
-                       return -EOPNOTSUPP;
-
-               if (ib_copy_from_udata(&ucmd, udata,
-                                      min(udata->inlen, sizeof(ucmd))))
-                       return -EFAULT;
+               err = ib_copy_validate_udata_in(udata, ucmd, ece_options);
+               if (err)
+                       return err;
 
                if (ucmd.comp_mask & ~MLX5_IB_MODIFY_QP_OOO_DP ||
                    memchr_inv(&ucmd.burst_info.reserved, 0,
@@ -5389,25 +5381,11 @@ static int prepare_user_rq(struct ib_pd *pd,
        struct mlx5_ib_dev *dev = to_mdev(pd->device);
        struct mlx5_ib_create_wq ucmd = {};
        int err;
-       size_t required_cmd_sz;
-
-       required_cmd_sz = offsetofend(struct mlx5_ib_create_wq,
-                                     single_stride_log_num_of_bytes);
-       if (udata->inlen < required_cmd_sz) {
-               mlx5_ib_dbg(dev, "invalid inlen\n");
-               return -EINVAL;
-       }
-
-       if (udata->inlen > sizeof(ucmd) &&
-           !ib_is_udata_cleared(udata, sizeof(ucmd),
-                                udata->inlen - sizeof(ucmd))) {
-               mlx5_ib_dbg(dev, "inlen is not supported\n");
-               return -EOPNOTSUPP;
-       }
-
-       if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) {
+       err = ib_copy_validate_udata_in(udata, ucmd,
+                                       single_stride_log_num_of_bytes);
+       if (err) {
                mlx5_ib_dbg(dev, "copy failed\n");
-               return -EFAULT;
+               return err;
        }
 
        if (ucmd.comp_mask & (~MLX5_IB_CREATE_WQ_STRIDING_RQ)) {
@@ -5626,7 +5604,6 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr 
*wq_attr,
        struct mlx5_ib_dev *dev = to_mdev(wq->device);
        struct mlx5_ib_rwq *rwq = to_mrwq(wq);
        struct mlx5_ib_modify_wq ucmd = {};
-       size_t required_cmd_sz;
        int curr_wq_state;
        int wq_state;
        int inlen;
@@ -5634,17 +5611,9 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct 
ib_wq_attr *wq_attr,
        void *rqc;
        void *in;
 
-       required_cmd_sz = offsetofend(struct mlx5_ib_modify_wq, reserved);
-       if (udata->inlen < required_cmd_sz)
-               return -EINVAL;
-
-       if (udata->inlen > sizeof(ucmd) &&
-           !ib_is_udata_cleared(udata, sizeof(ucmd),
-                                udata->inlen - sizeof(ucmd)))
-               return -EOPNOTSUPP;
-
-       if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)))
-               return -EFAULT;
+       err = ib_copy_validate_udata_in(udata, ucmd, reserved);
+       if (err)
+               return err;
 
        if (ucmd.comp_mask || ucmd.reserved)
                return -EOPNOTSUPP;
-- 
2.43.0


Reply via email to