goto error3;
        }
 
-       port_priv->pd = ib_alloc_pd(device);
+       port_priv->pd = ib_alloc_pd(device, 0);
        if (IS_ERR(port_priv->pd)) {
                dev_err(&device->dev, "Couldn't create ib_mad PD\n");
                ret = PTR_ERR(port_priv->pd);
 
  * Every PD has a local_dma_lkey which can be used as the lkey value for local
  * memory operations.
  */
-struct ib_pd *ib_alloc_pd(struct ib_device *device)
+struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
+               const char *caller)
 {
        struct ib_pd *pd;
+       int mr_access_flags = 0;
 
        pd = device->alloc_pd(device, NULL, NULL);
        if (IS_ERR(pd))
        pd->uobject = NULL;
        pd->__internal_mr = NULL;
        atomic_set(&pd->usecnt, 0);
+       pd->flags = flags;
 
        if (device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
                pd->local_dma_lkey = device->local_dma_lkey;
-       else {
+       else
+               mr_access_flags |= IB_ACCESS_LOCAL_WRITE;
+
+       if (flags & IB_PD_UNSAFE_GLOBAL_RKEY) {
+               pr_warn("%s: enabling unsafe global rkey\n", caller);
+               mr_access_flags |= IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE;
+       }
+
+       if (mr_access_flags) {
                struct ib_mr *mr;
 
-               mr = ib_get_dma_mr(pd, IB_ACCESS_LOCAL_WRITE);
+               mr = ib_get_dma_mr(pd, mr_access_flags);
                if (IS_ERR(mr)) {
                        ib_dealloc_pd(pd);
                        return (struct ib_pd *)mr;
                }
 
                pd->__internal_mr = mr;
-               pd->local_dma_lkey = pd->__internal_mr->lkey;
+
+               if (!(device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY))
+                       pd->local_dma_lkey = pd->__internal_mr->lkey;
+
+               if (flags & IB_PD_UNSAFE_GLOBAL_RKEY)
+                       pd->unsafe_global_rkey = pd->__internal_mr->rkey;
        }
+
        return pd;
 }
-EXPORT_SYMBOL(ib_alloc_pd);
+EXPORT_SYMBOL(__ib_alloc_pd);
 
 /**
  * ib_dealloc_pd - Deallocates a protection domain.
 
                goto err_buf;
        }
 
-       ctx->pd = ib_alloc_pd(ctx->ib_dev);
+       ctx->pd = ib_alloc_pd(ctx->ib_dev, 0);
        if (IS_ERR(ctx->pd)) {
                ret = PTR_ERR(ctx->pd);
                pr_err("Couldn't create tunnel PD (%d)\n", ret);
 
        if (err)
                goto err1;
 
-       xrcd->pd = ib_alloc_pd(ibdev);
+       xrcd->pd = ib_alloc_pd(ibdev, 0);
        if (IS_ERR(xrcd->pd)) {
                err = PTR_ERR(xrcd->pd);
                goto err2;
 
                goto error_0;
        }
 
-       pd = ib_alloc_pd(&dev->ib_dev);
+       pd = ib_alloc_pd(&dev->ib_dev, 0);
        if (IS_ERR(pd)) {
                mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
                ret = PTR_ERR(pd);
 
        int ret, size;
        int i;
 
-       priv->pd = ib_alloc_pd(priv->ca);
+       priv->pd = ib_alloc_pd(priv->ca, 0);
        if (IS_ERR(priv->pd)) {
                printk(KERN_WARNING "%s: failed to allocate PD\n", ca->name);
                return -ENODEV;
 
                  device->comps_used, ib_dev->name,
                  ib_dev->num_comp_vectors, max_cqe);
 
-       device->pd = ib_alloc_pd(ib_dev);
+       device->pd = ib_alloc_pd(ib_dev, 0);
        if (IS_ERR(device->pd))
                goto pd_err;
 
 
        if (ret)
                goto out;
 
-       device->pd = ib_alloc_pd(ib_dev);
+       device->pd = ib_alloc_pd(ib_dev, 0);
        if (IS_ERR(device->pd)) {
                ret = PTR_ERR(device->pd);
                isert_err("failed to allocate pd, device %p, ret=%d\n",
 
        INIT_LIST_HEAD(&srp_dev->dev_list);
 
        srp_dev->dev = device;
-       srp_dev->pd  = ib_alloc_pd(device);
+       srp_dev->pd  = ib_alloc_pd(device, 0);
        if (IS_ERR(srp_dev->pd))
                goto free_dev;
 
 
        init_waitqueue_head(&sdev->ch_releaseQ);
        mutex_init(&sdev->mutex);
 
-       sdev->pd = ib_alloc_pd(device);
+       sdev->pd = ib_alloc_pd(device, 0);
        if (IS_ERR(sdev->pd))
                goto free_dev;
 
 
        ndev->dev = cm_id->device;
        kref_init(&ndev->ref);
 
-       ndev->pd = ib_alloc_pd(ndev->dev);
+       ndev->pd = ib_alloc_pd(ndev->dev, 0);
        if (IS_ERR(ndev->pd))
                goto out_free_dev;
 
 
        ndev->device = cm_id->device;
        kref_init(&ndev->ref);
 
-       ndev->pd = ib_alloc_pd(ndev->device);
+       ndev->pd = ib_alloc_pd(ndev->device, 0);
        if (IS_ERR(ndev->pd))
                goto out_free_dev;
 
 
        hdev->ibh_cmid  = cmid;
        hdev->ibh_ibdev = cmid->device;
 
-       pd = ib_alloc_pd(cmid->device);
+       pd = ib_alloc_pd(cmid->device, 0);
        if (IS_ERR(pd)) {
                rc = PTR_ERR(pd);
                CERROR("Can't allocate PD: %d\n", rc);
 
 
 struct ib_pd {
        u32                     local_dma_lkey;
+       u32                     flags;
        struct ib_device       *device;
        struct ib_uobject      *uobject;
        atomic_t                usecnt; /* count all resources */
 
+       u32                     unsafe_global_rkey;
+
        /*
         * Implementation details of the RDMA core, don't use in drivers:
         */
 int ib_find_pkey(struct ib_device *device,
                 u8 port_num, u16 pkey, u16 *index);
 
-struct ib_pd *ib_alloc_pd(struct ib_device *device);
+enum ib_pd_flags {
+       /*
+        * Create a memory registration for all memory in the system and place
+        * the rkey for it into pd->unsafe_global_rkey.  This can be used by
+        * ULPs to avoid the overhead of dynamic MRs.
+        *
+        * This flag is generally considered unsafe and must only be used in
+        * extremly trusted environments.  Every use of it will log a warning
+        * in the kernel log.
+        */
+       IB_PD_UNSAFE_GLOBAL_RKEY        = 0x01,
+};
 
+struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
+               const char *caller);
+#define ib_alloc_pd(device, flags) \
+       __ib_alloc_pd((device), (flags), __func__)
 void ib_dealloc_pd(struct ib_pd *pd);
 
 /**
 
                goto error;
 
        /* Create the Protection Domain */
-       rdma->pd = ib_alloc_pd(rdma->cm_id->device);
+       rdma->pd = ib_alloc_pd(rdma->cm_id->device, 0);
        if (IS_ERR(rdma->pd))
                goto error;
 
 
        rds_ibdev->max_responder_resources = device->attrs.max_qp_rd_atom;
 
        rds_ibdev->dev = device;
-       rds_ibdev->pd = ib_alloc_pd(device);
+       rds_ibdev->pd = ib_alloc_pd(device, 0);
        if (IS_ERR(rds_ibdev->pd)) {
                rds_ibdev->pd = NULL;
                goto put_dev;
 
        newxprt->sc_ord = min_t(size_t, dev->attrs.max_qp_rd_atom, newxprt->sc_ord);
        newxprt->sc_ord = min_t(size_t, svcrdma_ord, newxprt->sc_ord);
 
-       newxprt->sc_pd = ib_alloc_pd(dev);
+       newxprt->sc_pd = ib_alloc_pd(dev, 0);
        if (IS_ERR(newxprt->sc_pd)) {
                dprintk("svcrdma: error creating PD for connect request\n");
                goto errout;
 
        }
        ia->ri_device = ia->ri_id->device;
 
-       ia->ri_pd = ib_alloc_pd(ia->ri_device);
+       ia->ri_pd = ib_alloc_pd(ia->ri_device, 0);
        if (IS_ERR(ia->ri_pd)) {
                rc = PTR_ERR(ia->ri_pd);
                pr_err("rpcrdma: ib_alloc_pd() returned %d\n", rc);