Skip to content

Commit 84cf229

Browse files
selvintxavierjgunthorpe
authored andcommitted
RDMA/bnxt_re: Fix the qp table indexing
qp->id can be a value outside the max number of qp. Indexing the qp table with the id can cause out of bounds crash. So changing the qp table indexing by (qp->id % max_qp -1). Allocating one extra entry for QP1. Some adapters create one more than the max_qp requested to accommodate QP1. If the qp->id is 1, store the inforamtion in the last entry of the qp table. Fixes: f218d67 ("RDMA/bnxt_re: Allow posting when QPs are in error") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Selvin Xavier <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 2d0e60e commit 84cf229

File tree

3 files changed

+25
-12
lines changed

3 files changed

+25
-12
lines changed

drivers/infiniband/hw/bnxt_re/qplib_fp.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
818818
u16 cmd_flags = 0;
819819
u32 qp_flags = 0;
820820
u8 pg_sz_lvl;
821+
u32 tbl_indx;
821822
int rc;
822823

823824
RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags);
@@ -907,8 +908,9 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
907908
rq->dbinfo.db = qp->dpi->dbr;
908909
rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
909910
}
910-
rcfw->qp_tbl[qp->id].qp_id = qp->id;
911-
rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
911+
tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
912+
rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
913+
rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;
912914

913915
return 0;
914916

@@ -959,6 +961,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
959961
u16 cmd_flags = 0;
960962
u32 qp_flags = 0;
961963
u8 pg_sz_lvl;
964+
u32 tbl_indx;
962965
u16 nsge;
963966

964967
RCFW_CMD_PREP(req, CREATE_QP, cmd_flags);
@@ -1111,8 +1114,9 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
11111114
rq->dbinfo.db = qp->dpi->dbr;
11121115
rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
11131116
}
1114-
rcfw->qp_tbl[qp->id].qp_id = qp->id;
1115-
rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
1117+
tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
1118+
rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
1119+
rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;
11161120

11171121
return 0;
11181122
fail:
@@ -1457,19 +1461,21 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
14571461
struct cmdq_destroy_qp req;
14581462
struct creq_destroy_qp_resp resp;
14591463
u16 cmd_flags = 0;
1464+
u32 tbl_indx;
14601465
int rc;
14611466

1462-
rcfw->qp_tbl[qp->id].qp_id = BNXT_QPLIB_QP_ID_INVALID;
1463-
rcfw->qp_tbl[qp->id].qp_handle = NULL;
1467+
tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
1468+
rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID;
1469+
rcfw->qp_tbl[tbl_indx].qp_handle = NULL;
14641470

14651471
RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags);
14661472

14671473
req.qp_cid = cpu_to_le32(qp->id);
14681474
rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
14691475
(void *)&resp, NULL, 0);
14701476
if (rc) {
1471-
rcfw->qp_tbl[qp->id].qp_id = qp->id;
1472-
rcfw->qp_tbl[qp->id].qp_handle = qp;
1477+
rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
1478+
rcfw->qp_tbl[tbl_indx].qp_handle = qp;
14731479
return rc;
14741480
}
14751481

drivers/infiniband/hw/bnxt_re/qplib_rcfw.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,14 +307,15 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
307307
__le16 mcookie;
308308
u16 cookie;
309309
int rc = 0;
310-
u32 qp_id;
310+
u32 qp_id, tbl_indx;
311311

312312
pdev = rcfw->pdev;
313313
switch (qp_event->event) {
314314
case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
315315
err_event = (struct creq_qp_error_notification *)qp_event;
316316
qp_id = le32_to_cpu(err_event->xid);
317-
qp = rcfw->qp_tbl[qp_id].qp_handle;
317+
tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw);
318+
qp = rcfw->qp_tbl[tbl_indx].qp_handle;
318319
dev_dbg(&pdev->dev, "Received QP error notification\n");
319320
dev_dbg(&pdev->dev,
320321
"qpid 0x%x, req_err=0x%x, resp_err=0x%x\n",
@@ -615,8 +616,9 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
615616

616617
cmdq->bmap_size = bmap_size;
617618

618-
rcfw->qp_tbl_size = qp_tbl_sz;
619-
rcfw->qp_tbl = kcalloc(qp_tbl_sz, sizeof(struct bnxt_qplib_qp_node),
619+
/* Allocate one extra to hold the QP1 entries */
620+
rcfw->qp_tbl_size = qp_tbl_sz + 1;
621+
rcfw->qp_tbl = kcalloc(rcfw->qp_tbl_size, sizeof(struct bnxt_qplib_qp_node),
620622
GFP_KERNEL);
621623
if (!rcfw->qp_tbl)
622624
goto fail;

drivers/infiniband/hw/bnxt_re/qplib_rcfw.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,9 @@ int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw);
216216
int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
217217
struct bnxt_qplib_ctx *ctx, int is_virtfn);
218218
void bnxt_qplib_mark_qp_error(void *qp_handle);
219+
static inline u32 map_qp_id_to_tbl_indx(u32 qid, struct bnxt_qplib_rcfw *rcfw)
220+
{
221+
/* Last index of the qp_tbl is for QP1 ie. qp_tbl_size - 1*/
222+
return (qid == 1) ? rcfw->qp_tbl_size - 1 : qid % rcfw->qp_tbl_size - 2;
223+
}
219224
#endif /* __BNXT_QPLIB_RCFW_H__ */

0 commit comments

Comments
 (0)