aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorBryan O'Sullivan <bos@pathscale.com>2006-09-28 12:00:07 -0400
committerRoland Dreier <rolandd@cisco.com>2006-09-28 14:16:41 -0400
commit6a553af286653818bb5831f1b351eefdc8a93b61 (patch)
treef37156843f767f7609b266dd42675c812767966a /drivers/infiniband
parent10aeb0e6d8823c1cccf9edc8401c848745c128be (diff)
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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_keys.c12
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mr.c3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c8
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ruc.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_uc.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h11
7 files changed, 26 insertions, 29 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_keys.c b/drivers/infiniband/hw/ipath/ipath_keys.c
index ba1b93226caa..9a6cbd05adcd 100644
--- a/drivers/infiniband/hw/ipath/ipath_keys.c
+++ b/drivers/infiniband/hw/ipath/ipath_keys.c
@@ -118,9 +118,10 @@ void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey)
118 * Check the IB SGE for validity and initialize our internal version 118 * Check the IB SGE for validity and initialize our internal version
119 * of it. 119 * of it.
120 */ 120 */
121int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, 121int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge,
122 struct ib_sge *sge, int acc) 122 struct ib_sge *sge, int acc)
123{ 123{
124 struct ipath_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
124 struct ipath_mregion *mr; 125 struct ipath_mregion *mr;
125 unsigned n, m; 126 unsigned n, m;
126 size_t off; 127 size_t off;
@@ -140,7 +141,8 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
140 goto bail; 141 goto bail;
141 } 142 }
142 mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))]; 143 mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))];
143 if (unlikely(mr == NULL || mr->lkey != sge->lkey)) { 144 if (unlikely(mr == NULL || mr->lkey != sge->lkey ||
145 qp->ibqp.pd != mr->pd)) {
144 ret = 0; 146 ret = 0;
145 goto bail; 147 goto bail;
146 } 148 }
@@ -188,9 +190,10 @@ bail:
188 * 190 *
189 * Return 1 if successful, otherwise 0. 191 * Return 1 if successful, otherwise 0.
190 */ 192 */
191int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, 193int ipath_rkey_ok(struct ipath_qp *qp, struct ipath_sge_state *ss,
192 u32 len, u64 vaddr, u32 rkey, int acc) 194 u32 len, u64 vaddr, u32 rkey, int acc)
193{ 195{
196 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
194 struct ipath_lkey_table *rkt = &dev->lk_table; 197 struct ipath_lkey_table *rkt = &dev->lk_table;
195 struct ipath_sge *sge = &ss->sge; 198 struct ipath_sge *sge = &ss->sge;
196 struct ipath_mregion *mr; 199 struct ipath_mregion *mr;
@@ -214,7 +217,8 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
214 } 217 }
215 218
216 mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))]; 219 mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
217 if (unlikely(mr == NULL || mr->lkey != rkey)) { 220 if (unlikely(mr == NULL || mr->lkey != rkey ||
221 qp->ibqp.pd != mr->pd)) {
218 ret = 0; 222 ret = 0;
219 goto bail; 223 goto bail;
220 } 224 }
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index b36f6fb3e37a..a0673c1eef71 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -138,6 +138,7 @@ struct ib_mr *ipath_reg_phys_mr(struct ib_pd *pd,
138 goto bail; 138 goto bail;
139 } 139 }
140 140
141 mr->mr.pd = pd;
141 mr->mr.user_base = *iova_start; 142 mr->mr.user_base = *iova_start;
142 mr->mr.iova = *iova_start; 143 mr->mr.iova = *iova_start;
143 mr->mr.length = 0; 144 mr->mr.length = 0;
@@ -197,6 +198,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
197 goto bail; 198 goto bail;
198 } 199 }
199 200
201 mr->mr.pd = pd;
200 mr->mr.user_base = region->user_base; 202 mr->mr.user_base = region->user_base;
201 mr->mr.iova = region->virt_base; 203 mr->mr.iova = region->virt_base;
202 mr->mr.length = region->length; 204 mr->mr.length = region->length;
@@ -289,6 +291,7 @@ struct ib_fmr *ipath_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
289 * Resources are allocated but no valid mapping (RKEY can't be 291 * Resources are allocated but no valid mapping (RKEY can't be
290 * used). 292 * used).
291 */ 293 */
294 fmr->mr.pd = pd;
292 fmr->mr.user_base = 0; 295 fmr->mr.user_base = 0;
293 fmr->mr.iova = 0; 296 fmr->mr.iova = 0;
294 fmr->mr.length = 0; 297 fmr->mr.length = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index 898f996513f8..595941b2b1bd 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -1234,7 +1234,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
1234 * Address range must be a subset of the original 1234 * Address range must be a subset of the original
1235 * request and start on pmtu boundaries. 1235 * request and start on pmtu boundaries.
1236 */ 1236 */
1237 ok = ipath_rkey_ok(dev, &qp->s_rdma_sge, 1237 ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
1238 qp->s_rdma_len, vaddr, rkey, 1238 qp->s_rdma_len, vaddr, rkey,
1239 IB_ACCESS_REMOTE_READ); 1239 IB_ACCESS_REMOTE_READ);
1240 if (unlikely(!ok)) { 1240 if (unlikely(!ok)) {
@@ -1532,7 +1532,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
1532 int ok; 1532 int ok;
1533 1533
1534 /* Check rkey & NAK */ 1534 /* Check rkey & NAK */
1535 ok = ipath_rkey_ok(dev, &qp->r_sge, 1535 ok = ipath_rkey_ok(qp, &qp->r_sge,
1536 qp->r_len, vaddr, rkey, 1536 qp->r_len, vaddr, rkey,
1537 IB_ACCESS_REMOTE_WRITE); 1537 IB_ACCESS_REMOTE_WRITE);
1538 if (unlikely(!ok)) 1538 if (unlikely(!ok))
@@ -1574,7 +1574,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
1574 int ok; 1574 int ok;
1575 1575
1576 /* Check rkey & NAK */ 1576 /* Check rkey & NAK */
1577 ok = ipath_rkey_ok(dev, &qp->s_rdma_sge, 1577 ok = ipath_rkey_ok(qp, &qp->s_rdma_sge,
1578 qp->s_rdma_len, vaddr, rkey, 1578 qp->s_rdma_len, vaddr, rkey,
1579 IB_ACCESS_REMOTE_READ); 1579 IB_ACCESS_REMOTE_READ);
1580 if (unlikely(!ok)) { 1580 if (unlikely(!ok)) {
@@ -1633,7 +1633,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
1633 goto nack_inv; 1633 goto nack_inv;
1634 rkey = be32_to_cpu(ateth->rkey); 1634 rkey = be32_to_cpu(ateth->rkey);
1635 /* Check rkey & NAK */ 1635 /* Check rkey & NAK */
1636 if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, 1636 if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge,
1637 sizeof(u64), vaddr, rkey, 1637 sizeof(u64), vaddr, rkey,
1638 IB_ACCESS_REMOTE_ATOMIC))) 1638 IB_ACCESS_REMOTE_ATOMIC)))
1639 goto nack_acc; 1639 goto nack_acc;
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index 5c1da2d25e03..17ae23fb1e40 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -108,7 +108,6 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp)
108 108
109static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe) 109static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
110{ 110{
111 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
112 int user = to_ipd(qp->ibqp.pd)->user; 111 int user = to_ipd(qp->ibqp.pd)->user;
113 int i, j, ret; 112 int i, j, ret;
114 struct ib_wc wc; 113 struct ib_wc wc;
@@ -119,8 +118,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe)
119 continue; 118 continue;
120 /* Check LKEY */ 119 /* Check LKEY */
121 if ((user && wqe->sg_list[i].lkey == 0) || 120 if ((user && wqe->sg_list[i].lkey == 0) ||
122 !ipath_lkey_ok(&dev->lk_table, 121 !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i],
123 &qp->r_sg_list[j], &wqe->sg_list[i],
124 IB_ACCESS_LOCAL_WRITE)) 122 IB_ACCESS_LOCAL_WRITE))
125 goto bad_lkey; 123 goto bad_lkey;
126 qp->r_len += wqe->sg_list[i].length; 124 qp->r_len += wqe->sg_list[i].length;
@@ -326,7 +324,7 @@ again:
326 case IB_WR_RDMA_WRITE: 324 case IB_WR_RDMA_WRITE:
327 if (wqe->length == 0) 325 if (wqe->length == 0)
328 break; 326 break;
329 if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, wqe->length, 327 if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
330 wqe->wr.wr.rdma.remote_addr, 328 wqe->wr.wr.rdma.remote_addr,
331 wqe->wr.wr.rdma.rkey, 329 wqe->wr.wr.rdma.rkey,
332 IB_ACCESS_REMOTE_WRITE))) { 330 IB_ACCESS_REMOTE_WRITE))) {
@@ -350,7 +348,7 @@ again:
350 break; 348 break;
351 349
352 case IB_WR_RDMA_READ: 350 case IB_WR_RDMA_READ:
353 if (unlikely(!ipath_rkey_ok(dev, &sqp->s_sge, wqe->length, 351 if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
354 wqe->wr.wr.rdma.remote_addr, 352 wqe->wr.wr.rdma.remote_addr,
355 wqe->wr.wr.rdma.rkey, 353 wqe->wr.wr.rdma.rkey,
356 IB_ACCESS_REMOTE_READ))) 354 IB_ACCESS_REMOTE_READ)))
@@ -365,7 +363,7 @@ again:
365 363
366 case IB_WR_ATOMIC_CMP_AND_SWP: 364 case IB_WR_ATOMIC_CMP_AND_SWP:
367 case IB_WR_ATOMIC_FETCH_AND_ADD: 365 case IB_WR_ATOMIC_FETCH_AND_ADD:
368 if (unlikely(!ipath_rkey_ok(dev, &qp->r_sge, sizeof(u64), 366 if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
369 wqe->wr.wr.rdma.remote_addr, 367 wqe->wr.wr.rdma.remote_addr,
370 wqe->wr.wr.rdma.rkey, 368 wqe->wr.wr.rdma.rkey,
371 IB_ACCESS_REMOTE_ATOMIC))) 369 IB_ACCESS_REMOTE_ATOMIC)))
@@ -575,8 +573,7 @@ int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr)
575 } 573 }
576 if (wr->sg_list[i].length == 0) 574 if (wr->sg_list[i].length == 0)
577 continue; 575 continue;
578 if (!ipath_lkey_ok(&to_idev(qp->ibqp.device)->lk_table, 576 if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i],
579 &wqe->sg_list[j], &wr->sg_list[i],
580 acc)) { 577 acc)) {
581 spin_unlock_irqrestore(&qp->s_lock, flags); 578 spin_unlock_irqrestore(&qp->s_lock, flags);
582 ret = -EINVAL; 579 ret = -EINVAL;
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
index d550b7aedb8d..e636cfd67a82 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -444,7 +444,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
444 int ok; 444 int ok;
445 445
446 /* Check rkey */ 446 /* Check rkey */
447 ok = ipath_rkey_ok(dev, &qp->r_sge, qp->r_len, 447 ok = ipath_rkey_ok(qp, &qp->r_sge, qp->r_len,
448 vaddr, rkey, 448 vaddr, rkey,
449 IB_ACCESS_REMOTE_WRITE); 449 IB_ACCESS_REMOTE_WRITE);
450 if (unlikely(!ok)) { 450 if (unlikely(!ok)) {
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 6991d1d74e3c..49f1102af8b3 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -39,7 +39,6 @@
39static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, 39static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
40 u32 *lengthp, struct ipath_sge_state *ss) 40 u32 *lengthp, struct ipath_sge_state *ss)
41{ 41{
42 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
43 int user = to_ipd(qp->ibqp.pd)->user; 42 int user = to_ipd(qp->ibqp.pd)->user;
44 int i, j, ret; 43 int i, j, ret;
45 struct ib_wc wc; 44 struct ib_wc wc;
@@ -50,8 +49,7 @@ static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe,
50 continue; 49 continue;
51 /* Check LKEY */ 50 /* Check LKEY */
52 if ((user && wqe->sg_list[i].lkey == 0) || 51 if ((user && wqe->sg_list[i].lkey == 0) ||
53 !ipath_lkey_ok(&dev->lk_table, 52 !ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge,
54 j ? &ss->sg_list[j - 1] : &ss->sge,
55 &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE)) 53 &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
56 goto bad_lkey; 54 goto bad_lkey;
57 *lengthp += wqe->sg_list[i].length; 55 *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 341
344 if (wr->sg_list[i].length == 0) 342 if (wr->sg_list[i].length == 0)
345 continue; 343 continue;
346 if (!ipath_lkey_ok(&dev->lk_table, ss.num_sge ? 344 if (!ipath_lkey_ok(qp, ss.num_sge ?
347 sg_list + ss.num_sge - 1 : &ss.sge, 345 sg_list + ss.num_sge - 1 : &ss.sge,
348 &wr->sg_list[i], 0)) { 346 &wr->sg_list[i], 0)) {
349 ret = -EINVAL; 347 ret = -EINVAL;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 3fffaa02e669..3597d362e5dd 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -220,6 +220,7 @@ struct ipath_segarray {
220}; 220};
221 221
222struct ipath_mregion { 222struct ipath_mregion {
223 struct ib_pd *pd; /* shares refcnt of ibmr.pd */
223 u64 user_base; /* User's address for this region */ 224 u64 user_base; /* User's address for this region */
224 u64 iova; /* IB start address of this region */ 225 u64 iova; /* IB start address of this region */
225 size_t length; 226 size_t length;
@@ -657,12 +658,6 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
657 658
658void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); 659void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig);
659 660
660int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
661 u32 len, u64 vaddr, u32 rkey, int acc);
662
663int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
664 struct ib_sge *sge, int acc);
665
666void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length); 661void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length);
667 662
668void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); 663void ipath_skip_sge(struct ipath_sge_state *ss, u32 length);
@@ -687,10 +682,10 @@ int ipath_alloc_lkey(struct ipath_lkey_table *rkt,
687 682
688void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey); 683void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey);
689 684
690int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, 685int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge,
691 struct ib_sge *sge, int acc); 686 struct ib_sge *sge, int acc);
692 687
693int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, 688int ipath_rkey_ok(struct ipath_qp *qp, struct ipath_sge_state *ss,
694 u32 len, u64 vaddr, u32 rkey, int acc); 689 u32 len, u64 vaddr, u32 rkey, int acc);
695 690
696int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, 691int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,