]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
RDMA/mlx5: Handle udate outlen checks in one place
authorLeon Romanovsky <leonro@mellanox.com>
Mon, 27 Apr 2020 15:46:32 +0000 (18:46 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 30 Apr 2020 21:45:45 +0000 (18:45 -0300)
Place in one function all udata size checks. This will allow
us move ib_copy_to_udata() in general place and ensure that
it will be performed after call to the FW.

Link: https://lore.kernel.org/r/20200427154636.381474-33-leon@kernel.org
Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/mlx5/qp.c

index 8daa8bc6b9c7367c20269b79ea898bc588f32f0a..0d06706e6ce1f8cb74bca00fccce38cf7cf9ca70 100644 (file)
@@ -1613,6 +1613,7 @@ static void destroy_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *q
 struct mlx5_create_qp_params {
        struct ib_udata *udata;
        size_t inlen;
+       size_t outlen;
        void *ucmd;
        u8 is_rss_raw : 1;
        struct ib_qp_init_attr *attr;
@@ -1638,15 +1639,9 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        void *hfso;
        u32 selected_fields = 0;
        u32 outer_l4;
-       size_t min_resp_len;
        u32 tdn = mucontext->tdn;
        u8 lb_flag = 0;
 
-       min_resp_len =
-               offsetof(typeof(resp), bfreg_index) + sizeof(resp.bfreg_index);
-       if (udata->outlen < min_resp_len)
-               return -EINVAL;
-
        if (ucmd->comp_mask) {
                mlx5_ib_dbg(dev, "invalid comp mask\n");
                return -EOPNOTSUPP;
@@ -2780,26 +2775,43 @@ static int process_create_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
        return (create_flags) ? -EINVAL : 0;
 }
 
-static size_t process_udata_size(struct ib_qp_init_attr *attr,
-                                struct ib_udata *udata)
+static int process_udata_size(struct mlx5_ib_dev *dev,
+                             struct mlx5_create_qp_params *params)
 {
        size_t ucmd = sizeof(struct mlx5_ib_create_qp);
+       struct ib_qp_init_attr *attr = params->attr;
+       struct ib_udata *udata = params->udata;
+       size_t outlen = udata->outlen;
        size_t inlen = udata->inlen;
 
-       if (attr->qp_type == IB_QPT_DRIVER)
-               return (inlen < ucmd) ? 0 : ucmd;
+       params->outlen = min(outlen, sizeof(struct mlx5_ib_create_qp_resp));
+       if (attr->qp_type == IB_QPT_DRIVER) {
+               params->inlen = (inlen < ucmd) ? 0 : ucmd;
+               goto out;
+       }
 
-       if (!attr->rwq_ind_tbl)
-               return ucmd;
+       if (!params->is_rss_raw) {
+               params->inlen = ucmd;
+               goto out;
+       }
 
+       /* RSS RAW QP */
        if (inlen < offsetofend(struct mlx5_ib_create_qp_rss, flags))
-               return 0;
+               return -EINVAL;
+
+       if (outlen < offsetofend(struct mlx5_ib_create_qp_resp, bfreg_index))
+               return -EINVAL;
 
        ucmd = sizeof(struct mlx5_ib_create_qp_rss);
        if (inlen > ucmd && !ib_is_udata_cleared(udata, ucmd, inlen - ucmd))
-               return 0;
+               return -EINVAL;
+
+       params->inlen = min(ucmd, inlen);
+out:
+       if (!params->inlen)
+               mlx5_ib_dbg(dev, "udata is too small or not cleared\n");
 
-       return min(ucmd, inlen);
+       return (params->inlen) ? 0 : -EINVAL;
 }
 
 static int create_raw_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
@@ -2883,9 +2895,9 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attr,
        params.is_rss_raw = !!attr->rwq_ind_tbl;
 
        if (udata) {
-               params.inlen = process_udata_size(attr, udata);
-               if (!params.inlen)
-                       return ERR_PTR(-EINVAL);
+               err = process_udata_size(dev, &params);
+               if (err)
+                       return ERR_PTR(err);
 
                params.ucmd = kzalloc(params.inlen, GFP_KERNEL);
                if (!params.ucmd)