diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2006-09-28 12:00:07 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-09-28 14:16:41 -0400 |
commit | 6a553af286653818bb5831f1b351eefdc8a93b61 (patch) | |
tree | f37156843f767f7609b266dd42675c812767966a /drivers | |
parent | 10aeb0e6d8823c1cccf9edc8401c848745c128be (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')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_keys.c | 12 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_mr.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_rc.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ruc.c | 13 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_uc.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ud.c | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.h | 11 |
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 | */ |
121 | int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, | 121 | int 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 | */ |
191 | int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, | 193 | int 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 | ||
109 | static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe) | 109 | static 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 @@ | |||
39 | static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | 39 | static 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 | ||
222 | struct ipath_mregion { | 222 | struct 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 | ||
658 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); | 659 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); |
659 | 660 | ||
660 | int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, | ||
661 | u32 len, u64 vaddr, u32 rkey, int acc); | ||
662 | |||
663 | int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, | ||
664 | struct ib_sge *sge, int acc); | ||
665 | |||
666 | void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length); | 661 | void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length); |
667 | 662 | ||
668 | void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); | 663 | 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 | 682 | ||
688 | void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey); | 683 | void ipath_free_lkey(struct ipath_lkey_table *rkt, u32 lkey); |
689 | 684 | ||
690 | int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge, | 685 | int 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 | ||
693 | int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, | 688 | int 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 | ||
696 | int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | 691 | int ipath_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, |