IB/core: Make sure that PSN does not overflow
authorMajd Dibbiny <majd@mellanox.com>
Tue, 14 Nov 2017 12:51:56 +0000 (14:51 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 27 Dec 2017 22:40:35 +0000 (15:40 -0700)
The rq/sq->psn is 24 bits as defined in the IB spec, therefore we mask
out the 8 most significant bits to avoid overflow in modify_qp.

Signed-off-by: Majd Dibbiny <majd@mellanox.com>
Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
Reviewed-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/verbs.c

index 43e0254..b53fb0e 100644 (file)
@@ -1320,6 +1320,7 @@ static int ib_resolve_eth_dmac(struct ib_device *device,
 int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
                            int attr_mask, struct ib_udata *udata)
 {
+       u8 port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
        int ret;
 
        if (attr_mask & IB_QP_AV) {
@@ -1327,6 +1328,21 @@ int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
                if (ret)
                        return ret;
        }
+
+       if (rdma_ib_or_roce(qp->device, port)) {
+               if (attr_mask & IB_QP_RQ_PSN && attr->rq_psn & ~0xffffff) {
+                       pr_warn("%s: %s rq_psn overflow, masking to 24 bits\n",
+                               __func__, qp->device->name);
+                       attr->rq_psn &= 0xffffff;
+               }
+
+               if (attr_mask & IB_QP_SQ_PSN && attr->sq_psn & ~0xffffff) {
+                       pr_warn("%s: %s sq_psn overflow, masking to 24 bits\n",
+                               __func__, qp->device->name);
+                       attr->sq_psn &= 0xffffff;
+               }
+       }
+
        ret = ib_security_modify_qp(qp, attr, attr_mask, udata);
        if (!ret && (attr_mask & IB_QP_PORT))
                qp->port = attr->port_num;