Commit 84cf229f authored by Selvin Xavier's avatar Selvin Xavier Committed by Jason Gunthorpe

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: f218d67e ("RDMA/bnxt_re: Allow posting when QPs are in error")
Link: https://lore.kernel.org/r/1598292876-26529-4-git-send-email-selvin.xavier@broadcom.comSigned-off-by: default avatarSelvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 2d0e60ee
...@@ -818,6 +818,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) ...@@ -818,6 +818,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
u16 cmd_flags = 0; u16 cmd_flags = 0;
u32 qp_flags = 0; u32 qp_flags = 0;
u8 pg_sz_lvl; u8 pg_sz_lvl;
u32 tbl_indx;
int rc; int rc;
RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags); 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) ...@@ -907,8 +908,9 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
rq->dbinfo.db = qp->dpi->dbr; rq->dbinfo.db = qp->dpi->dbr;
rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size); rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
} }
rcfw->qp_tbl[qp->id].qp_id = qp->id; tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
rcfw->qp_tbl[qp->id].qp_handle = (void *)qp; rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;
return 0; return 0;
...@@ -959,6 +961,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) ...@@ -959,6 +961,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
u16 cmd_flags = 0; u16 cmd_flags = 0;
u32 qp_flags = 0; u32 qp_flags = 0;
u8 pg_sz_lvl; u8 pg_sz_lvl;
u32 tbl_indx;
u16 nsge; u16 nsge;
RCFW_CMD_PREP(req, CREATE_QP, cmd_flags); 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) ...@@ -1111,8 +1114,9 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
rq->dbinfo.db = qp->dpi->dbr; rq->dbinfo.db = qp->dpi->dbr;
rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size); rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
} }
rcfw->qp_tbl[qp->id].qp_id = qp->id; tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
rcfw->qp_tbl[qp->id].qp_handle = (void *)qp; rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;
return 0; return 0;
fail: fail:
...@@ -1457,10 +1461,12 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, ...@@ -1457,10 +1461,12 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
struct cmdq_destroy_qp req; struct cmdq_destroy_qp req;
struct creq_destroy_qp_resp resp; struct creq_destroy_qp_resp resp;
u16 cmd_flags = 0; u16 cmd_flags = 0;
u32 tbl_indx;
int rc; int rc;
rcfw->qp_tbl[qp->id].qp_id = BNXT_QPLIB_QP_ID_INVALID; tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
rcfw->qp_tbl[qp->id].qp_handle = NULL; rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID;
rcfw->qp_tbl[tbl_indx].qp_handle = NULL;
RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags); RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags);
...@@ -1468,8 +1474,8 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, ...@@ -1468,8 +1474,8 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
(void *)&resp, NULL, 0); (void *)&resp, NULL, 0);
if (rc) { if (rc) {
rcfw->qp_tbl[qp->id].qp_id = qp->id; rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
rcfw->qp_tbl[qp->id].qp_handle = qp; rcfw->qp_tbl[tbl_indx].qp_handle = qp;
return rc; return rc;
} }
......
...@@ -307,14 +307,15 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, ...@@ -307,14 +307,15 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
__le16 mcookie; __le16 mcookie;
u16 cookie; u16 cookie;
int rc = 0; int rc = 0;
u32 qp_id; u32 qp_id, tbl_indx;
pdev = rcfw->pdev; pdev = rcfw->pdev;
switch (qp_event->event) { switch (qp_event->event) {
case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION: case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
err_event = (struct creq_qp_error_notification *)qp_event; err_event = (struct creq_qp_error_notification *)qp_event;
qp_id = le32_to_cpu(err_event->xid); qp_id = le32_to_cpu(err_event->xid);
qp = rcfw->qp_tbl[qp_id].qp_handle; tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw);
qp = rcfw->qp_tbl[tbl_indx].qp_handle;
dev_dbg(&pdev->dev, "Received QP error notification\n"); dev_dbg(&pdev->dev, "Received QP error notification\n");
dev_dbg(&pdev->dev, dev_dbg(&pdev->dev,
"qpid 0x%x, req_err=0x%x, resp_err=0x%x\n", "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, ...@@ -615,8 +616,9 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
cmdq->bmap_size = bmap_size; cmdq->bmap_size = bmap_size;
rcfw->qp_tbl_size = qp_tbl_sz; /* Allocate one extra to hold the QP1 entries */
rcfw->qp_tbl = kcalloc(qp_tbl_sz, sizeof(struct bnxt_qplib_qp_node), rcfw->qp_tbl_size = qp_tbl_sz + 1;
rcfw->qp_tbl = kcalloc(rcfw->qp_tbl_size, sizeof(struct bnxt_qplib_qp_node),
GFP_KERNEL); GFP_KERNEL);
if (!rcfw->qp_tbl) if (!rcfw->qp_tbl)
goto fail; goto fail;
......
...@@ -216,4 +216,9 @@ int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw); ...@@ -216,4 +216,9 @@ int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw);
int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw, int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
struct bnxt_qplib_ctx *ctx, int is_virtfn); struct bnxt_qplib_ctx *ctx, int is_virtfn);
void bnxt_qplib_mark_qp_error(void *qp_handle); void bnxt_qplib_mark_qp_error(void *qp_handle);
static inline u32 map_qp_id_to_tbl_indx(u32 qid, struct bnxt_qplib_rcfw *rcfw)
{
/* Last index of the qp_tbl is for QP1 ie. qp_tbl_size - 1*/
return (qid == 1) ? rcfw->qp_tbl_size - 1 : qid % rcfw->qp_tbl_size - 2;
}
#endif /* __BNXT_QPLIB_RCFW_H__ */ #endif /* __BNXT_QPLIB_RCFW_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment