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

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

Signed-off-by: default avatarBryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 10aeb0e6
...@@ -118,9 +118,10 @@ void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey) ...@@ -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 * Check the IB SGE for validity and initialize our internal version
* of it. * 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 ib_sge *sge, int acc)
{ {
struct ipath_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
struct ipath_mregion *mr; struct ipath_mregion *mr;
unsigned n, m; unsigned n, m;
size_t off; size_t off;
...@@ -140,7 +141,8 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, ...@@ -140,7 +141,8 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
goto bail; goto bail;
} }
mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))]; 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; ret = 0;
goto bail; goto bail;
} }
...@@ -188,9 +190,10 @@ bail: ...@@ -188,9 +190,10 @@ bail:
* *
* Return 1 if successful, otherwise 0. * 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) 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_lkey_table *rkt = &dev->lk_table;
struct ipath_sge *sge = &ss->sge; struct ipath_sge *sge = &ss->sge;
struct ipath_mregion *mr; struct ipath_mregion *mr;
...@@ -214,7 +217,8 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, ...@@ -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))]; 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; ret = 0;
goto bail; goto bail;
} }
......
...@@ -138,6 +138,7 @@ struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd, ...@@ -138,6 +138,7 @@ struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd,
goto bail; goto bail;
} }
mr->mr.pd = pd;
mr->mr.user_base = *iova_start; mr->mr.user_base = *iova_start;
mr->mr.iova = *iova_start; mr->mr.iova = *iova_start;
mr->mr.length = 0; mr->mr.length = 0;
...@@ -197,6 +198,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region, ...@@ -197,6 +198,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
goto bail; goto bail;
} }
mr->mr.pd = pd;
mr->mr.user_base = region->user_base; mr->mr.user_base = region->user_base;
mr->mr.iova = region->virt_base; mr->mr.iova = region->virt_base;
mr->mr.length = region->length; mr->mr.length = region->length;
...@@ -289,6 +291,7 @@ struct ib_fmr *ipath_alloc_fmr(struct ib_pd *pd, int mr_access_flags, ...@@ -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 * Resources are allocated but no valid mapping (RKEY can't be
* used). * used).
*/ */
fmr->mr.pd = pd;
fmr->mr.user_base = 0; fmr->mr.user_base = 0;
fmr->mr.iova = 0; fmr->mr.iova = 0;
fmr->mr.length = 0; fmr->mr.length = 0;
......
...@@ -1234,7 +1234,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, ...@@ -1234,7 +1234,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
* Address range must be a subset of the original * Address range must be a subset of the original
* request and start on pmtu boundaries. * 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, qp->s_rdma_len, vaddr, rkey,
IB_ACCESS_REMOTE_READ); IB_ACCESS_REMOTE_READ);
if (unlikely(!ok)) { if (unlikely(!ok)) {
...@@ -1532,7 +1532,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -1532,7 +1532,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
int ok; int ok;
/* Check rkey & NAK */ /* Check rkey & NAK */
ok = ipath_rkey_ok(dev, &qp->r_sge, ok = ipath_rkey_ok(qp, &qp->r_sge,
qp->r_len, vaddr, rkey, qp->r_len, vaddr, rkey,
IB_ACCESS_REMOTE_WRITE); IB_ACCESS_REMOTE_WRITE);
if (unlikely(!ok)) if (unlikely(!ok))
...@@ -1574,7 +1574,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -1574,7 +1574,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
int ok; int ok;
/* Check rkey & NAK */ /* 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, qp->s_rdma_len, vaddr, rkey,
IB_ACCESS_REMOTE_READ); IB_ACCESS_REMOTE_READ);
if (unlikely(!ok)) { if (unlikely(!ok)) {
...@@ -1633,7 +1633,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -1633,7 +1633,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
goto nack_inv; goto nack_inv;
rkey = be32_to_cpu(ateth->rkey); rkey = be32_to_cpu(ateth->rkey);
/* Check rkey & NAK */ /* 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, sizeof(u64), vaddr, rkey,
IB_ACCESS_REMOTE_ATOMIC))) IB_ACCESS_REMOTE_ATOMIC)))
goto nack_acc; goto nack_acc;
......
...@@ -108,7 +108,6 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp) ...@@ -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) 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 user = to_ipd(qp->ibqp.pd)->user;
int i, j, ret; int i, j, ret;
struct ib_wc wc; struct ib_wc wc;
...@@ -119,8 +118,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe) ...@@ -119,8 +118,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
continue; continue;
/* Check LKEY */ /* Check LKEY */
if ((user && wqe->sg_list[i].lkey == 0) || if ((user && wqe->sg_list[i].lkey == 0) ||
!ipath_lkey_ok(&dev->lk_table, !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i],
&qp->r_sg_list[j], &wqe->sg_list[i],
IB_ACCESS_LOCAL_WRITE)) IB_ACCESS_LOCAL_WRITE))
goto bad_lkey; goto bad_lkey;
qp->r_len += wqe->sg_list[i].length; qp->r_len += wqe->sg_list[i].length;
...@@ -326,7 +324,7 @@ again: ...@@ -326,7 +324,7 @@ again:
case IB_WR_RDMA_WRITE: case IB_WR_RDMA_WRITE:
if (wqe->length == 0) if (wqe->length == 0)
break; 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.remote_addr,
wqe->wr.wr.rdma.rkey, wqe->wr.wr.rdma.rkey,
IB_ACCESS_REMOTE_WRITE))) { IB_ACCESS_REMOTE_WRITE))) {
...@@ -350,7 +348,7 @@ again: ...@@ -350,7 +348,7 @@ again:
break; break;
case IB_WR_RDMA_READ: 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.remote_addr,
wqe->wr.wr.rdma.rkey, wqe->wr.wr.rdma.rkey,
IB_ACCESS_REMOTE_READ))) IB_ACCESS_REMOTE_READ)))
...@@ -365,7 +363,7 @@ again: ...@@ -365,7 +363,7 @@ again:
case IB_WR_ATOMIC_CMP_AND_SWP: case IB_WR_ATOMIC_CMP_AND_SWP:
case IB_WR_ATOMIC_FETCH_AND_ADD: 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.remote_addr,
wqe->wr.wr.rdma.rkey, wqe->wr.wr.rdma.rkey,
IB_ACCESS_REMOTE_ATOMIC))) IB_ACCESS_REMOTE_ATOMIC)))
...@@ -575,8 +573,7 @@ int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr) ...@@ -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) if (wr->sg_list[i].length == 0)
continue; continue;
if (!ipath_lkey_ok(&to_idev(qp->ibqp.device)->lk_table, if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i],
&wqe->sg_list[j], &wr->sg_list[i],
acc)) { acc)) {
spin_unlock_irqrestore(&qp->s_lock, flags); spin_unlock_irqrestore(&qp->s_lock, flags);
ret = -EINVAL; ret = -EINVAL;
......
...@@ -444,7 +444,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, ...@@ -444,7 +444,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
int ok; int ok;
/* Check rkey */ /* 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, vaddr, rkey,
IB_ACCESS_REMOTE_WRITE); IB_ACCESS_REMOTE_WRITE);
if (unlikely(!ok)) { if (unlikely(!ok)) {
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
u32 *lengthp, struct ipath_sge_state *ss) u32 *lengthp, struct ipath_sge_state *ss)
{ {
struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
int user = to_ipd(qp->ibqp.pd)->user; int user = to_ipd(qp->ibqp.pd)->user;
int i, j, ret; int i, j, ret;
struct ib_wc wc; struct ib_wc wc;
...@@ -50,8 +49,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, ...@@ -50,8 +49,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
continue; continue;
/* Check LKEY */ /* Check LKEY */
if ((user && wqe->sg_list[i].lkey == 0) || if ((user && wqe->sg_list[i].lkey == 0) ||
!ipath_lkey_ok(&dev->lk_table, !ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge,
j ? &ss->sg_list[j - 1] : &ss->sge,
&wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE)) &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
goto bad_lkey; goto bad_lkey;
*lengthp += wqe->sg_list[i].length; *lengthp += wqe->sg_list[i].length;
...@@ -343,7 +341,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) ...@@ -343,7 +341,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
if (wr->sg_list[i].length == 0) if (wr->sg_list[i].length == 0)
continue; continue;
if (!ipath_lkey_ok(&dev->lk_table, ss.num_sge ? if (!ipath_lkey_ok(qp, ss.num_sge ?
sg_list + ss.num_sge - 1 : &ss.sge, sg_list + ss.num_sge - 1 : &ss.sge,
&wr->sg_list[i], 0)) { &wr->sg_list[i], 0)) {
ret = -EINVAL; ret = -EINVAL;
......
...@@ -220,6 +220,7 @@ struct ipath_segarray { ...@@ -220,6 +220,7 @@ struct ipath_segarray {
}; };
struct ipath_mregion { struct ipath_mregion {
struct ib_pd *pd; /* shares refcnt of ibmr.pd */
u64 user_base; /* User's address for this region */ u64 user_base; /* User's address for this region */
u64 iova; /* IB start address of this region */ u64 iova; /* IB start address of this region */
size_t length; size_t length;
...@@ -657,12 +658,6 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, ...@@ -657,12 +658,6 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig);
int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
u32 len, u64 vaddr, u32 rkey, int acc);
int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
struct ib_sge *sge, int acc);
void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length); void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length);
void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); void ipath_skip_sge(struct ipath_sge_state *ss, u32 length);
...@@ -687,10 +682,10 @@ int ipath_alloc_lkey(struct ipath_lkey_table *rkt, ...@@ -687,10 +682,10 @@ int ipath_alloc_lkey(struct ipath_lkey_table *rkt,
void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey); void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey);
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 ib_sge *sge, int acc);
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); u32 len, u64 vaddr, u32 rkey, int acc);
int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
......
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