]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/efa: Validate SQ ring size against max LLQ size
authorYonatan Nachum <ynachum@amazon.com>
Tue, 26 May 2026 08:15:36 +0000 (08:15 +0000)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 2 Jun 2026 17:48:59 +0000 (14:48 -0300)
Validate the SQ ring size against the device's max LLQ size. This
ensures that when using 128-byte WQEs, userspace cannot exceed the queue
limits.

On create QP, userspace provides the SQ ring size (depth x WQE size)
which is validated against the max LLQ size.

Fixes: 40909f664d27 ("RDMA/efa: Add EFA verbs implementation")
Link: https://patch.msgid.link/r/20260526081536.1203553-1-ynachum@amazon.com
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/efa/efa_verbs.c

index 7bd0838ebc99e414b05db079c81f3162eef9d783..9b2b652800e443f01a0be80cf1348aa1aa7f70e4 100644 (file)
@@ -613,7 +613,8 @@ err_remove_mmap:
 }
 
 static int efa_qp_validate_cap(struct efa_dev *dev,
-                              struct ib_qp_init_attr *init_attr)
+                              struct ib_qp_init_attr *init_attr,
+                              u32 sq_ring_size)
 {
        if (init_attr->cap.max_send_wr > dev->dev_attr.max_sq_depth) {
                ibdev_dbg(&dev->ibdev,
@@ -622,6 +623,14 @@ static int efa_qp_validate_cap(struct efa_dev *dev,
                          dev->dev_attr.max_sq_depth);
                return -EINVAL;
        }
+
+       if (sq_ring_size > dev->dev_attr.max_llq_size) {
+               ibdev_dbg(&dev->ibdev,
+                         "qp: requested sq ring size[%u] exceeds the max[%u]\n",
+                         sq_ring_size, dev->dev_attr.max_llq_size);
+               return -EINVAL;
+       }
+
        if (init_attr->cap.max_recv_wr > dev->dev_attr.max_rq_depth) {
                ibdev_dbg(&dev->ibdev,
                          "qp: requested receive wr[%u] exceeds the max[%u]\n",
@@ -691,14 +700,6 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
        ucontext = rdma_udata_to_drv_context(udata, struct efa_ucontext,
                                             ibucontext);
 
-       err = efa_qp_validate_cap(dev, init_attr);
-       if (err)
-               goto err_out;
-
-       err = efa_qp_validate_attr(dev, init_attr);
-       if (err)
-               goto err_out;
-
        err = ib_copy_validate_udata_in_cm(udata, cmd, driver_qp_type, 0);
        if (err)
                goto err_out;
@@ -720,6 +721,14 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
                goto err_out;
        }
 
+       err = efa_qp_validate_cap(dev, init_attr, cmd.sq_ring_size);
+       if (err)
+               goto err_out;
+
+       err = efa_qp_validate_attr(dev, init_attr);
+       if (err)
+               goto err_out;
+
        create_qp_params.uarn = ucontext->uarn;
        create_qp_params.pd = to_epd(ibqp->pd)->pdn;