diff mbox series

[for-next,v7,18/19] rdma_rxe: add rkey validation checks for MR and MW

Message ID 20201001174847.4268-19-rpearson@hpe.com (mailing list archive)
State Changes Requested
Headers show
Series rdma_rxe: API extensions | expand

Commit Message

Bob Pearson Oct. 1, 2020, 5:48 p.m. UTC
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@hpe.com>
---
 drivers/infiniband/sw/rxe/rxe_mr.c | 49 ++++++++++++++++++++++++++++++
 drivers/infiniband/sw/rxe/rxe_mw.c | 10 +++++-
 2 files changed, 58 insertions(+), 1 deletion(-)
diff mbox series

Patch

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;
 	}