mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-11 15:49:56 +00:00
IB/ipath: Ensure that PD of MR matches PD of QP checking the Rkey
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
10aeb0e6d8
commit
6a553af286
@ -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 @@ bail:
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 @@ again:
|
||||
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 @@ again:
|
||||
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 @@ again:
|
||||
|
||||
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;
|
||||
|
@ -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)) {
|
||||
|
@ -39,7 +39,6 @@
|
||||
static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
|
||||
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 i, j, ret;
|
||||
struct ib_wc wc;
|
||||
@ -50,8 +49,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,
|
||||
j ? &ss->sg_list[j - 1] : &ss->sge,
|
||||
!ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge,
|
||||
&wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
|
||||
goto bad_lkey;
|
||||
*lengthp += wqe->sg_list[i].length;
|
||||
@ -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)
|
||||
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,
|
||||
&wr->sg_list[i], 0)) {
|
||||
ret = -EINVAL;
|
||||
|
@ -220,6 +220,7 @@ struct ipath_segarray {
|
||||
};
|
||||
|
||||
struct ipath_mregion {
|
||||
struct ib_pd *pd; /* shares refcnt of ibmr.pd */
|
||||
u64 user_base; /* User's address for this region */
|
||||
u64 iova; /* IB start address of this region */
|
||||
size_t length;
|
||||
@ -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);
|
||||
|
||||
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_skip_sge(struct ipath_sge_state *ss, u32 length);
|
||||
@ -687,10 +682,10 @@ int ipath_alloc_lkey(struct ipath_lkey_table *rkt,
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
|
||||
|
Loading…
x
Reference in New Issue
Block a user