Added checks from 9.4.1.1.3 r_key validation for remote memory invalidate to MR and MW invalidate routines. Signed-off-by: Bob Pearson <rpearson@xxxxxxx> --- drivers/infiniband/sw/rxe/rxe_mr.c | 49 ++++++++++++++++++++++++++++++ drivers/infiniband/sw/rxe/rxe_mw.c | 10 +++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index 1901f388c747..2cc3487d3f77 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -522,8 +522,57 @@ int advance_dma_data(struct rxe_dma_info *dma, unsigned int length) return 0; } +static int check_invalidate_mr(struct rxe_qp *qp, struct rxe_mr *mr) +{ + int type = mr->ibmr.type; + int qpt = qp_type(qp); + + if (unlikely(type > IB_MR_TYPE_INTEGRITY)) { + pr_err("invalidate: MR of unknown type = %d\n", + mr->ibmr.type); + return -EINVAL; + } + + /* o10-37.2.13 */ + if (unlikely(type == IB_MR_TYPE_MEM_REG || + type == IB_MR_TYPE_USER)) { + pr_err("invalidate: MR created by reg_mr or user_reg_mr\n"); + return -EINVAL; + } + + /* o10-37.2.17 */ + if (unlikely(atomic_read(&mr->num_mw))) { + pr_err("invalidate: MR with bound MWs\n"); + return -EINVAL; + } + + if (unlikely(!((qpt == IB_QPT_RC) || (qpt == IB_QPT_UC) || + (qpt == IB_QPT_XRC_INI) || (qpt == IB_QPT_XRC_TGT)))) { + pr_err("invalidate: MR with invalid QP type\n"); + return -EINVAL; + } + + if (unlikely(qp->ibqp.pd != mr->ibmr.pd)) { + pr_err("invalidate: MR and QP have different PDs\n"); + return -EINVAL; + } + + if (unlikely(mr->state == RXE_MEM_STATE_INVALID)) { + pr_err("invalidate: MR in invalid state\n"); + return -EINVAL; + } + + return 0; +} + int rxe_invalidate_mr(struct rxe_qp *qp, struct rxe_mr *mr) { + int ret; + + ret = check_invalidate_mr(qp, mr); + if (ret) + return ret; + /* TODO there are API rules being ignored here * cleanup later. Current project is not trying * to fix MR diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c index d2d09502a28d..ecda634ab7f0 100644 --- a/drivers/infiniband/sw/rxe/rxe_mw.c +++ b/drivers/infiniband/sw/rxe/rxe_mw.c @@ -316,9 +316,17 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe) static int check_invalidate_mw(struct rxe_qp *qp, struct rxe_mw *mw) { + int qpt = qp_type(qp); + /* o10-37.2.26 */ if (unlikely(mw->ibmw.type == IB_MW_TYPE_1)) { - pr_err_once("attempt to invalidate a type 1 MW\n"); + pr_err_once("invalidate a type 1 MW\n"); + return -EINVAL; + } + + if (unlikely(!((qpt == IB_QPT_RC) || (qpt == IB_QPT_UC) || + (qpt == IB_QPT_XRC_INI) || (qpt == IB_QPT_XRC_TGT)))) { + pr_err("invalidate Mw with invalid QP type\n"); return -EINVAL; } -- 2.25.1