From: Jiaran Zhang <zhangjia...@huawei.com>

[ Upstream commit 172505cfa3a8ee98acaa569fd3be97697b333958 ]

According to the RoCE v1 specification, the sl (service level) 0-7 are
mapped directly to priorities 0-7 respectively, sl 8-15 are reserved. The
driver should verify whether the the value of sl is larger than 7, if so,
an exception should be returned.

Fixes: 926a01dc000d ("RDMA/hns: Add QP operations support for hip08 SoC")
Link: 
https://lore.kernel.org/r/1600509802-44382-5-git-send-email-liweih...@huawei.com
Signed-off-by: Jiaran Zhang <zhangjia...@huawei.com>
Signed-off-by: Weihang Li <liweih...@huawei.com>
Signed-off-by: Jason Gunthorpe <j...@nvidia.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 12 ++++++++++--
 drivers/infiniband/hw/hns/hns_roce_hw_v2.h |  2 ++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 38a48ab3e1d02..0f995aa23b9a9 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -4287,11 +4287,19 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp,
                       V2_QPC_BYTE_28_FL_S, 0);
        memcpy(context->dgid, grh->dgid.raw, sizeof(grh->dgid.raw));
        memset(qpc_mask->dgid, 0, sizeof(grh->dgid.raw));
+
+       hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr);
+       if (unlikely(hr_qp->sl > MAX_SERVICE_LEVEL)) {
+               ibdev_err(ibdev,
+                         "failed to fill QPC, sl (%d) shouldn't be larger than 
%d.\n",
+                         hr_qp->sl, MAX_SERVICE_LEVEL);
+               return -EINVAL;
+       }
+
        roce_set_field(context->byte_28_at_fl, V2_QPC_BYTE_28_SL_M,
-                      V2_QPC_BYTE_28_SL_S, rdma_ah_get_sl(&attr->ah_attr));
+                      V2_QPC_BYTE_28_SL_S, hr_qp->sl);
        roce_set_field(qpc_mask->byte_28_at_fl, V2_QPC_BYTE_28_SL_M,
                       V2_QPC_BYTE_28_SL_S, 0);
-       hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr);
 
        return 0;
 }
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h 
b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index 4f840997c6c73..c6a280bdbfaaf 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -1957,6 +1957,8 @@ struct hns_roce_eq_context {
 #define HNS_ROCE_V2_AEQE_EVENT_QUEUE_NUM_S 0
 #define HNS_ROCE_V2_AEQE_EVENT_QUEUE_NUM_M GENMASK(23, 0)
 
+#define MAX_SERVICE_LEVEL 0x7
+
 struct hns_roce_wqe_atomic_seg {
        __le64          fetchadd_swap_data;
        __le64          cmp_data;
-- 
2.25.1



Reply via email to