* 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;
                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;
        }
  *
  * 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;
        }
 
        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;
        }
 
                goto bail;
        }
 
+       mr->mr.pd = pd;
        mr->mr.user_base = *iova_start;
        mr->mr.iova = *iova_start;
        mr->mr.length = 0;
                goto bail;
        }
 
+       mr->mr.pd = pd;
        mr->mr.user_base = region->user_base;
        mr->mr.iova = region->virt_base;
        mr->mr.length = region->length;
         * 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;
 
                         * 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)) {
                        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))
                        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)) {
                        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;
 
 
 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;
                        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;
        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))) {
                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)))
 
        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)))
                }
                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;
 
                        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)) {
 
 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;
                        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;
 
                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;
 
 };
 
 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;
 
 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);
 
 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,