Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a553af2 authored by Bryan O'Sullivan's avatar Bryan O'Sullivan Committed by Roland Dreier
Browse files

IB/ipath: Ensure that PD of MR matches PD of QP checking the Rkey

parent 10aeb0e6
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -118,9 +118,10 @@ void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey)
 * Check the IB SGE for validity and initialize our internal version
 * of it.
 */
int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge,
		  struct ib_sge *sge, int acc)
{
	struct ipath_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
	struct ipath_mregion *mr;
	unsigned n, m;
	size_t off;
@@ -140,7 +141,8 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
		goto bail;
	}
	mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))];
	if (unlikely(mr == NULL || mr->lkey != sge->lkey)) {
	if (unlikely(mr == NULL || mr->lkey != sge->lkey ||
		     qp->ibqp.pd != mr->pd)) {
		ret = 0;
		goto bail;
	}
@@ -188,9 +190,10 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
 *
 * Return 1 if successful, otherwise 0.
 */
int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
int ipath_rkey_ok(struct ipath_qp *qp, struct ipath_sge_state *ss,
		  u32 len, u64 vaddr, u32 rkey, int acc)
{
	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
	struct ipath_lkey_table *rkt = &dev->lk_table;
	struct ipath_sge *sge = &ss->sge;
	struct ipath_mregion *mr;
@@ -214,7 +217,8 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
	}

	mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
	if (unlikely(mr == NULL || mr->lkey != rkey)) {
	if (unlikely(mr == NULL || mr->lkey != rkey ||
		     qp->ibqp.pd != mr->pd)) {
		ret = 0;
		goto bail;
	}
+3 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd,
		goto bail;
	}

	mr->mr.pd = pd;
	mr->mr.user_base = *iova_start;
	mr->mr.iova = *iova_start;
	mr->mr.length = 0;
@@ -197,6 +198,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
		goto bail;
	}

	mr->mr.pd = pd;
	mr->mr.user_base = region->user_base;
	mr->mr.iova = region->virt_base;
	mr->mr.length = region->length;
@@ -289,6 +291,7 @@ struct ib_fmr *ipath_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
	 * Resources are allocated but no valid mapping (RKEY can't be
	 * used).
	 */
	fmr->mr.pd = pd;
	fmr->mr.user_base = 0;
	fmr->mr.iova = 0;
	fmr->mr.length = 0;
+4 −4
Original line number Diff line number Diff line
@@ -1234,7 +1234,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
			 * Address range must be a subset of the original
			 * request and start on pmtu boundaries.
			 */
			ok = ipath_rkey_ok(dev, &qp->s_rdma_sge,
			ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
					   qp->s_rdma_len, vaddr, rkey,
					   IB_ACCESS_REMOTE_READ);
			if (unlikely(!ok)) {
@@ -1532,7 +1532,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
			int ok;

			/* Check rkey & NAK */
			ok = ipath_rkey_ok(dev, &qp->r_sge,
			ok = ipath_rkey_ok(qp, &qp->r_sge,
					   qp->r_len, vaddr, rkey,
					   IB_ACCESS_REMOTE_WRITE);
			if (unlikely(!ok))
@@ -1574,7 +1574,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
			int ok;

			/* Check rkey & NAK */
			ok = ipath_rkey_ok(dev, &qp->s_rdma_sge,
			ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
					   qp->s_rdma_len, vaddr, rkey,
					   IB_ACCESS_REMOTE_READ);
			if (unlikely(!ok)) {
@@ -1633,7 +1633,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
			goto nack_inv;
		rkey = be32_to_cpu(ateth->rkey);
		/* Check rkey & NAK */
		if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge,
		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge,
					    sizeof(u64), vaddr, rkey,
					    IB_ACCESS_REMOTE_ATOMIC)))
			goto nack_acc;
+5 −8
Original line number Diff line number Diff line
@@ -108,7 +108,6 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp)

static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
{
	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
	int user = to_ipd(qp->ibqp.pd)->user;
	int i, j, ret;
	struct ib_wc wc;
@@ -119,8 +118,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
			continue;
		/* Check LKEY */
		if ((user && wqe->sg_list[i].lkey == 0) ||
		    !ipath_lkey_ok(&dev->lk_table,
				   &qp->r_sg_list[j], &wqe->sg_list[i],
		    !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i],
				   IB_ACCESS_LOCAL_WRITE))
			goto bad_lkey;
		qp->r_len += wqe->sg_list[i].length;
@@ -326,7 +324,7 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp)
	case IB_WR_RDMA_WRITE:
		if (wqe->length == 0)
			break;
		if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, wqe->length,
		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
					    wqe->wr.wr.rdma.remote_addr,
					    wqe->wr.wr.rdma.rkey,
					    IB_ACCESS_REMOTE_WRITE))) {
@@ -350,7 +348,7 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp)
		break;

	case IB_WR_RDMA_READ:
		if (unlikely(!ipath_rkey_ok(dev, &sqp->s_sge, wqe->length,
		if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
					    wqe->wr.wr.rdma.remote_addr,
					    wqe->wr.wr.rdma.rkey,
					    IB_ACCESS_REMOTE_READ)))
@@ -365,7 +363,7 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp)

	case IB_WR_ATOMIC_CMP_AND_SWP:
	case IB_WR_ATOMIC_FETCH_AND_ADD:
		if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, sizeof(u64),
		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
					    wqe->wr.wr.rdma.remote_addr,
					    wqe->wr.wr.rdma.rkey,
					    IB_ACCESS_REMOTE_ATOMIC)))
@@ -575,8 +573,7 @@ int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr)
		}
		if (wr->sg_list[i].length == 0)
			continue;
		if (!ipath_lkey_ok(&to_idev(qp->ibqp.device)->lk_table,
				   &wqe->sg_list[j], &wr->sg_list[i],
		if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i],
				   acc)) {
			spin_unlock_irqrestore(&qp->s_lock, flags);
			ret = -EINVAL;
+1 −1
Original line number Diff line number Diff line
@@ -444,7 +444,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
			int ok;

			/* Check rkey */
			ok = ipath_rkey_ok(dev, &qp->r_sge, qp->r_len,
			ok = ipath_rkey_ok(qp, &qp->r_sge, qp->r_len,
					   vaddr, rkey,
					   IB_ACCESS_REMOTE_WRITE);
			if (unlikely(!ok)) {
Loading