Blob Blame History Raw
From: Majd Dibbiny <majd@mellanox.com>
Date: Tue, 14 Nov 2017 14:51:56 +0200
Subject: IB/core: Make sure that PSN does not overflow
Patch-mainline: v4.16-rc1
Git-commit: 727b7e9a65c01569f8e4f9809d6f2be8c331c42a
References: bsc#1103992 FATE#326009

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>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 drivers/infiniband/core/verbs.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -1321,6 +1321,7 @@ static int ib_resolve_eth_dmac(struct ib
 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) {
@@ -1328,6 +1329,21 @@ int ib_modify_qp_with_udata(struct ib_qp
 		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;