Skip to content

Commit 5e617c1

Browse files
Luoyoumingrleon
authored andcommitted
RDMA/hns: Add check for SL
SL set by users may exceed the capability of devices. So add check for this situation. Fixes: fba429f ("RDMA/hns: Fix missing fields in address vector") Fixes: 70f9252 ("RDMA/hns: Use the reserved loopback QPs to free MR before destroying MPT") Fixes: f0cb411 ("RDMA/hns: Use new interface to modify QP context") Signed-off-by: Luoyouming <[email protected]> Signed-off-by: Junxian Huang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Leon Romanovsky <[email protected]>
1 parent b5f9eff commit 5e617c1

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

drivers/infiniband/hw/hns/hns_roce_ah.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
#include <linux/pci.h>
3434
#include <rdma/ib_addr.h>
3535
#include <rdma/ib_cache.h>
36+
#include "hnae3.h"
3637
#include "hns_roce_device.h"
38+
#include "hns_roce_hw_v2.h"
3739

3840
static inline u16 get_ah_udp_sport(const struct rdma_ah_attr *ah_attr)
3941
{
@@ -57,6 +59,7 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
5759
struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device);
5860
struct hns_roce_ah *ah = to_hr_ah(ibah);
5961
int ret = 0;
62+
u32 max_sl;
6063

6164
if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata)
6265
return -EOPNOTSUPP;
@@ -70,9 +73,17 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
7073
ah->av.hop_limit = grh->hop_limit;
7174
ah->av.flowlabel = grh->flow_label;
7275
ah->av.udp_sport = get_ah_udp_sport(ah_attr);
73-
ah->av.sl = rdma_ah_get_sl(ah_attr);
7476
ah->av.tclass = get_tclass(grh);
7577

78+
ah->av.sl = rdma_ah_get_sl(ah_attr);
79+
max_sl = min_t(u32, MAX_SERVICE_LEVEL, hr_dev->caps.sl_num - 1);
80+
if (unlikely(ah->av.sl > max_sl)) {
81+
ibdev_err_ratelimited(&hr_dev->ib_dev,
82+
"failed to set sl, sl (%u) shouldn't be larger than %u.\n",
83+
ah->av.sl, max_sl);
84+
return -EINVAL;
85+
}
86+
7687
memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE);
7788
memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN);
7889

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4826,22 +4826,32 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp,
48264826
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
48274827
struct ib_device *ibdev = &hr_dev->ib_dev;
48284828
const struct ib_gid_attr *gid_attr = NULL;
4829+
u8 sl = rdma_ah_get_sl(&attr->ah_attr);
48294830
int is_roce_protocol;
48304831
u16 vlan_id = 0xffff;
48314832
bool is_udp = false;
4833+
u32 max_sl;
48324834
u8 ib_port;
48334835
u8 hr_port;
48344836
int ret;
48354837

4838+
max_sl = min_t(u32, MAX_SERVICE_LEVEL, hr_dev->caps.sl_num - 1);
4839+
if (unlikely(sl > max_sl)) {
4840+
ibdev_err_ratelimited(ibdev,
4841+
"failed to fill QPC, sl (%u) shouldn't be larger than %u.\n",
4842+
sl, max_sl);
4843+
return -EINVAL;
4844+
}
4845+
48364846
/*
48374847
* If free_mr_en of qp is set, it means that this qp comes from
48384848
* free mr. This qp will perform the loopback operation.
48394849
* In the loopback scenario, only sl needs to be set.
48404850
*/
48414851
if (hr_qp->free_mr_en) {
4842-
hr_reg_write(context, QPC_SL, rdma_ah_get_sl(&attr->ah_attr));
4852+
hr_reg_write(context, QPC_SL, sl);
48434853
hr_reg_clear(qpc_mask, QPC_SL);
4844-
hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr);
4854+
hr_qp->sl = sl;
48454855
return 0;
48464856
}
48474857

@@ -4908,14 +4918,7 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp,
49084918
memcpy(context->dgid, grh->dgid.raw, sizeof(grh->dgid.raw));
49094919
memset(qpc_mask->dgid, 0, sizeof(grh->dgid.raw));
49104920

4911-
hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr);
4912-
if (unlikely(hr_qp->sl > MAX_SERVICE_LEVEL)) {
4913-
ibdev_err(ibdev,
4914-
"failed to fill QPC, sl (%u) shouldn't be larger than %d.\n",
4915-
hr_qp->sl, MAX_SERVICE_LEVEL);
4916-
return -EINVAL;
4917-
}
4918-
4921+
hr_qp->sl = sl;
49194922
hr_reg_write(context, QPC_SL, hr_qp->sl);
49204923
hr_reg_clear(qpc_mask, QPC_SL);
49214924

0 commit comments

Comments
 (0)