提交 ed082d36 编写于 作者: C Christoph Hellwig 提交者: Doug Ledford

IB/core: add support to create a unsafe global rkey to ib_create_pd

Instead of exposing ib_get_dma_mr to ULPs and letting them use it more or
less unchecked, this moves the capability of creating a global rkey into
the RDMA core, where it can be easily audited.  It also prints a warning
everytime this feature is used as well.
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Reviewed-by: NSagi Grimberg <sagi@grimberg.me>
Reviewed-by: NJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Reviewed-by: NSteve Wise <swise@opengridcomputing.com>
Signed-off-by: NDoug Ledford <dledford@redhat.com>
上级 50d46335
...@@ -3160,7 +3160,7 @@ static int ib_mad_port_open(struct ib_device *device, ...@@ -3160,7 +3160,7 @@ static int ib_mad_port_open(struct ib_device *device,
goto error3; goto error3;
} }
port_priv->pd = ib_alloc_pd(device); port_priv->pd = ib_alloc_pd(device, 0);
if (IS_ERR(port_priv->pd)) { if (IS_ERR(port_priv->pd)) {
dev_err(&device->dev, "Couldn't create ib_mad PD\n"); dev_err(&device->dev, "Couldn't create ib_mad PD\n");
ret = PTR_ERR(port_priv->pd); ret = PTR_ERR(port_priv->pd);
......
...@@ -227,9 +227,11 @@ EXPORT_SYMBOL(rdma_port_get_link_layer); ...@@ -227,9 +227,11 @@ EXPORT_SYMBOL(rdma_port_get_link_layer);
* Every PD has a local_dma_lkey which can be used as the lkey value for local * Every PD has a local_dma_lkey which can be used as the lkey value for local
* memory operations. * 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; struct ib_pd *pd;
int mr_access_flags = 0;
pd = device->alloc_pd(device, NULL, NULL); pd = device->alloc_pd(device, NULL, NULL);
if (IS_ERR(pd)) if (IS_ERR(pd))
...@@ -239,24 +241,39 @@ struct ib_pd *ib_alloc_pd(struct ib_device *device) ...@@ -239,24 +241,39 @@ struct ib_pd *ib_alloc_pd(struct ib_device *device)
pd->uobject = NULL; pd->uobject = NULL;
pd->__internal_mr = NULL; pd->__internal_mr = NULL;
atomic_set(&pd->usecnt, 0); atomic_set(&pd->usecnt, 0);
pd->flags = flags;
if (device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY) if (device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
pd->local_dma_lkey = 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; 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)) { if (IS_ERR(mr)) {
ib_dealloc_pd(pd); ib_dealloc_pd(pd);
return (struct ib_pd *)mr; return (struct ib_pd *)mr;
} }
pd->__internal_mr = 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; return pd;
} }
EXPORT_SYMBOL(ib_alloc_pd); EXPORT_SYMBOL(__ib_alloc_pd);
/** /**
* ib_dealloc_pd - Deallocates a protection domain. * ib_dealloc_pd - Deallocates a protection domain.
......
...@@ -1897,7 +1897,7 @@ static int create_pv_resources(struct ib_device *ibdev, int slave, int port, ...@@ -1897,7 +1897,7 @@ static int create_pv_resources(struct ib_device *ibdev, int slave, int port,
goto err_buf; 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)) { if (IS_ERR(ctx->pd)) {
ret = PTR_ERR(ctx->pd); ret = PTR_ERR(ctx->pd);
pr_err("Couldn't create tunnel PD (%d)\n", ret); pr_err("Couldn't create tunnel PD (%d)\n", ret);
......
...@@ -1259,7 +1259,7 @@ static struct ib_xrcd *mlx4_ib_alloc_xrcd(struct ib_device *ibdev, ...@@ -1259,7 +1259,7 @@ static struct ib_xrcd *mlx4_ib_alloc_xrcd(struct ib_device *ibdev,
if (err) if (err)
goto err1; goto err1;
xrcd->pd = ib_alloc_pd(ibdev); xrcd->pd = ib_alloc_pd(ibdev, 0);
if (IS_ERR(xrcd->pd)) { if (IS_ERR(xrcd->pd)) {
err = PTR_ERR(xrcd->pd); err = PTR_ERR(xrcd->pd);
goto err2; goto err2;
......
...@@ -2223,7 +2223,7 @@ static int create_umr_res(struct mlx5_ib_dev *dev) ...@@ -2223,7 +2223,7 @@ static int create_umr_res(struct mlx5_ib_dev *dev)
goto error_0; goto error_0;
} }
pd = ib_alloc_pd(&dev->ib_dev); pd = ib_alloc_pd(&dev->ib_dev, 0);
if (IS_ERR(pd)) { if (IS_ERR(pd)) {
mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n"); mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
ret = PTR_ERR(pd); ret = PTR_ERR(pd);
......
...@@ -147,7 +147,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) ...@@ -147,7 +147,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
int ret, size; int ret, size;
int i; int i;
priv->pd = ib_alloc_pd(priv->ca); priv->pd = ib_alloc_pd(priv->ca, 0);
if (IS_ERR(priv->pd)) { if (IS_ERR(priv->pd)) {
printk(KERN_WARNING "%s: failed to allocate PD\n", ca->name); printk(KERN_WARNING "%s: failed to allocate PD\n", ca->name);
return -ENODEV; return -ENODEV;
......
...@@ -88,7 +88,7 @@ static int iser_create_device_ib_res(struct iser_device *device) ...@@ -88,7 +88,7 @@ static int iser_create_device_ib_res(struct iser_device *device)
device->comps_used, ib_dev->name, device->comps_used, ib_dev->name,
ib_dev->num_comp_vectors, max_cqe); 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)) if (IS_ERR(device->pd))
goto pd_err; goto pd_err;
......
...@@ -309,7 +309,7 @@ isert_create_device_ib_res(struct isert_device *device) ...@@ -309,7 +309,7 @@ isert_create_device_ib_res(struct isert_device *device)
if (ret) if (ret)
goto out; goto out;
device->pd = ib_alloc_pd(ib_dev); device->pd = ib_alloc_pd(ib_dev, 0);
if (IS_ERR(device->pd)) { if (IS_ERR(device->pd)) {
ret = PTR_ERR(device->pd); ret = PTR_ERR(device->pd);
isert_err("failed to allocate pd, device %p, ret=%d\n", isert_err("failed to allocate pd, device %p, ret=%d\n",
......
...@@ -3573,7 +3573,7 @@ static void srp_add_one(struct ib_device *device) ...@@ -3573,7 +3573,7 @@ static void srp_add_one(struct ib_device *device)
INIT_LIST_HEAD(&srp_dev->dev_list); INIT_LIST_HEAD(&srp_dev->dev_list);
srp_dev->dev = device; 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)) if (IS_ERR(srp_dev->pd))
goto free_dev; goto free_dev;
......
...@@ -2475,7 +2475,7 @@ static void srpt_add_one(struct ib_device *device) ...@@ -2475,7 +2475,7 @@ static void srpt_add_one(struct ib_device *device)
init_waitqueue_head(&sdev->ch_releaseQ); init_waitqueue_head(&sdev->ch_releaseQ);
mutex_init(&sdev->mutex); mutex_init(&sdev->mutex);
sdev->pd = ib_alloc_pd(device); sdev->pd = ib_alloc_pd(device, 0);
if (IS_ERR(sdev->pd)) if (IS_ERR(sdev->pd))
goto free_dev; goto free_dev;
......
...@@ -446,7 +446,7 @@ nvme_rdma_find_get_device(struct rdma_cm_id *cm_id) ...@@ -446,7 +446,7 @@ nvme_rdma_find_get_device(struct rdma_cm_id *cm_id)
ndev->dev = cm_id->device; ndev->dev = cm_id->device;
kref_init(&ndev->ref); kref_init(&ndev->ref);
ndev->pd = ib_alloc_pd(ndev->dev); ndev->pd = ib_alloc_pd(ndev->dev, 0);
if (IS_ERR(ndev->pd)) if (IS_ERR(ndev->pd))
goto out_free_dev; goto out_free_dev;
......
...@@ -848,7 +848,7 @@ nvmet_rdma_find_get_device(struct rdma_cm_id *cm_id) ...@@ -848,7 +848,7 @@ nvmet_rdma_find_get_device(struct rdma_cm_id *cm_id)
ndev->device = cm_id->device; ndev->device = cm_id->device;
kref_init(&ndev->ref); kref_init(&ndev->ref);
ndev->pd = ib_alloc_pd(ndev->device); ndev->pd = ib_alloc_pd(ndev->device, 0);
if (IS_ERR(ndev->pd)) if (IS_ERR(ndev->pd))
goto out_free_dev; goto out_free_dev;
......
...@@ -2465,7 +2465,7 @@ int kiblnd_dev_failover(struct kib_dev *dev) ...@@ -2465,7 +2465,7 @@ int kiblnd_dev_failover(struct kib_dev *dev)
hdev->ibh_cmid = cmid; hdev->ibh_cmid = cmid;
hdev->ibh_ibdev = cmid->device; hdev->ibh_ibdev = cmid->device;
pd = ib_alloc_pd(cmid->device); pd = ib_alloc_pd(cmid->device, 0);
if (IS_ERR(pd)) { if (IS_ERR(pd)) {
rc = PTR_ERR(pd); rc = PTR_ERR(pd);
CERROR("Can't allocate PD: %d\n", rc); CERROR("Can't allocate PD: %d\n", rc);
......
...@@ -1370,10 +1370,13 @@ struct ib_udata { ...@@ -1370,10 +1370,13 @@ struct ib_udata {
struct ib_pd { struct ib_pd {
u32 local_dma_lkey; u32 local_dma_lkey;
u32 flags;
struct ib_device *device; struct ib_device *device;
struct ib_uobject *uobject; struct ib_uobject *uobject;
atomic_t usecnt; /* count all resources */ atomic_t usecnt; /* count all resources */
u32 unsafe_global_rkey;
/* /*
* Implementation details of the RDMA core, don't use in drivers: * Implementation details of the RDMA core, don't use in drivers:
*/ */
...@@ -2506,8 +2509,23 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid, ...@@ -2506,8 +2509,23 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid,
int ib_find_pkey(struct ib_device *device, int ib_find_pkey(struct ib_device *device,
u8 port_num, u16 pkey, u16 *index); 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); void ib_dealloc_pd(struct ib_pd *pd);
/** /**
......
...@@ -680,7 +680,7 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args) ...@@ -680,7 +680,7 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args)
goto error; goto error;
/* Create the Protection Domain */ /* 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)) if (IS_ERR(rdma->pd))
goto error; goto error;
......
...@@ -160,7 +160,7 @@ static void rds_ib_add_one(struct ib_device *device) ...@@ -160,7 +160,7 @@ static void rds_ib_add_one(struct ib_device *device)
rds_ibdev->max_responder_resources = device->attrs.max_qp_rd_atom; rds_ibdev->max_responder_resources = device->attrs.max_qp_rd_atom;
rds_ibdev->dev = device; 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)) { if (IS_ERR(rds_ibdev->pd)) {
rds_ibdev->pd = NULL; rds_ibdev->pd = NULL;
goto put_dev; goto put_dev;
......
...@@ -993,7 +993,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) ...@@ -993,7 +993,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
newxprt->sc_ord = min_t(size_t, dev->attrs.max_qp_rd_atom, newxprt->sc_ord); 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_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)) { if (IS_ERR(newxprt->sc_pd)) {
dprintk("svcrdma: error creating PD for connect request\n"); dprintk("svcrdma: error creating PD for connect request\n");
goto errout; goto errout;
......
...@@ -386,7 +386,7 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg) ...@@ -386,7 +386,7 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
} }
ia->ri_device = ia->ri_id->device; 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)) { if (IS_ERR(ia->ri_pd)) {
rc = PTR_ERR(ia->ri_pd); rc = PTR_ERR(ia->ri_pd);
pr_err("rpcrdma: ib_alloc_pd() returned %d\n", rc); pr_err("rpcrdma: ib_alloc_pd() returned %d\n", rc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册