@@ -3,6 +3,7 @@
* Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved.
* Copyright (c) 2005 PathScale, Inc. All rights reserved.
* Copyright (c) 2006 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2020 Intel Corporatiion. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -694,6 +695,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
struct ib_uobject *uobj;
struct ib_pd *pd;
struct ib_mr *mr;
+ struct ib_user_mr_attr user_mr_attr;
int ret;
struct ib_device *ib_dev;
@@ -727,8 +729,17 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
}
}
- mr = pd->device->ops.reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va,
- cmd.access_flags,
+ if (cmd.access_flags & IB_ACCESS_DMABUF) {
+ pr_debug("Dma-buf support not available via regular reg_mr call\n");
+ ret = -EINVAL;
+ goto err_put;
+ }
+
+ user_mr_attr.start = cmd.start;
+ user_mr_attr.length = cmd.length;
+ user_mr_attr.virt_addr = cmd.hca_va;
+ user_mr_attr.access_flags = cmd.access_flags;
+ mr = pd->device->ops.reg_user_mr(pd, &user_mr_attr,
&attrs->driver_udata);
if (IS_ERR(mr)) {
ret = PTR_ERR(mr);
@@ -769,6 +780,7 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
struct ib_pd *pd = NULL;
struct ib_mr *mr;
struct ib_pd *old_pd;
+ struct ib_user_mr_attr user_mr_attr;
int ret;
struct ib_uobject *uobj;
@@ -811,9 +823,12 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
}
old_pd = mr->pd;
- ret = mr->device->ops.rereg_user_mr(mr, cmd.flags, cmd.start,
- cmd.length, cmd.hca_va,
- cmd.access_flags, pd,
+ user_mr_attr.start = cmd.start;
+ user_mr_attr.length = cmd.length;
+ user_mr_attr.virt_addr = cmd.hca_va;
+ user_mr_attr.access_flags = cmd.access_flags;
+ ret = mr->device->ops.rereg_user_mr(mr, cmd.flags,
+ &user_mr_attr, pd,
&attrs->driver_udata);
if (ret)
goto put_uobj_pd;
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004 Infinicon Corporation. All rights reserved.
- * Copyright (c) 2004 Intel Corporation. All rights reserved.
+ * Copyright (c) 2004, 2020 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
@@ -2039,6 +2039,7 @@ int ib_resize_cq(struct ib_cq *cq, int cqe)
struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
u64 virt_addr, int access_flags)
{
+ struct ib_user_mr_attr attr;
struct ib_mr *mr;
if (access_flags & IB_ACCESS_ON_DEMAND) {
@@ -2049,8 +2050,16 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
}
}
- mr = pd->device->ops.reg_user_mr(pd, start, length, virt_addr,
- access_flags, NULL);
+ if (access_flags & IB_ACCESS_DMABUF) {
+ pr_debug("Dma-buf support not available via kernel Verbs\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ attr.start = start;
+ attr.length = length;
+ attr.virt_addr = virt_addr;
+ attr.access_flags = access_flags;
+ mr = pd->device->ops.reg_user_mr(pd, &attr, NULL);
if (IS_ERR(mr))
return mr;
@@ -3790,8 +3790,8 @@ static int fill_umem_pbl_tbl(struct ib_umem *umem, u64 *pbl_tbl_orig,
}
/* uverbs */
-struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags,
+struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
@@ -3801,9 +3801,9 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
u64 *pbl_tbl = NULL;
int umem_pgs, page_shift, rc;
- if (length > BNXT_RE_MAX_MR_SIZE) {
+ if (attr->length > BNXT_RE_MAX_MR_SIZE) {
ibdev_err(&rdev->ibdev, "MR Size: %lld > Max supported:%lld\n",
- length, BNXT_RE_MAX_MR_SIZE);
+ attr->length, BNXT_RE_MAX_MR_SIZE);
return ERR_PTR(-ENOMEM);
}
@@ -3813,7 +3813,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
mr->rdev = rdev;
mr->qplib_mr.pd = &pd->qplib_pd;
- mr->qplib_mr.flags = __from_ib_access_flags(mr_access_flags);
+ mr->qplib_mr.flags = __from_ib_access_flags(attr->access_flags);
mr->qplib_mr.type = CMDQ_ALLOCATE_MRW_MRW_FLAGS_MR;
rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr);
@@ -3824,7 +3824,8 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
/* The fixed portion of the rkey is the same as the lkey */
mr->ib_mr.rkey = mr->qplib_mr.rkey;
- umem = ib_umem_get(&rdev->ibdev, start, length, mr_access_flags);
+ umem = ib_umem_get(&rdev->ibdev, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(umem)) {
ibdev_err(&rdev->ibdev, "Failed to get umem");
rc = -EFAULT;
@@ -3832,14 +3833,14 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
}
mr->ib_umem = umem;
- mr->qplib_mr.va = virt_addr;
+ mr->qplib_mr.va = attr->virt_addr;
umem_pgs = ib_umem_page_count(umem);
if (!umem_pgs) {
ibdev_err(&rdev->ibdev, "umem is invalid!");
rc = -EINVAL;
goto free_umem;
}
- mr->qplib_mr.total_size = length;
+ mr->qplib_mr.total_size = attr->length;
pbl_tbl = kcalloc(umem_pgs, sizeof(u64 *), GFP_KERNEL);
if (!pbl_tbl) {
@@ -3849,7 +3850,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
page_shift = __ffs(ib_umem_find_best_pgsz(umem,
BNXT_RE_PAGE_SIZE_4K | BNXT_RE_PAGE_SIZE_2M,
- virt_addr));
+ attr->virt_addr));
if (!bnxt_re_page_size_ok(page_shift)) {
ibdev_err(&rdev->ibdev, "umem page size unsupported!");
@@ -3858,9 +3859,9 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
}
if (page_shift == BNXT_RE_PAGE_SHIFT_4K &&
- length > BNXT_RE_MAX_MR_SIZE_LOW) {
+ attr->length > BNXT_RE_MAX_MR_SIZE_LOW) {
ibdev_err(&rdev->ibdev, "Requested MR Sz:%llu Max sup:%llu",
- length, (u64)BNXT_RE_MAX_MR_SIZE_LOW);
+ attr->length, (u64)BNXT_RE_MAX_MR_SIZE_LOW);
rc = -EINVAL;
goto fail;
}
@@ -206,8 +206,8 @@ struct ib_mr *bnxt_re_alloc_mr(struct ib_pd *ib_pd, enum ib_mr_type mr_type,
struct ib_mw *bnxt_re_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type,
struct ib_udata *udata);
int bnxt_re_dealloc_mw(struct ib_mw *mw);
-struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags,
+struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata);
void bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
@@ -987,9 +987,9 @@ int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
void c4iw_dealloc(struct uld_ctx *ctx);
struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
struct ib_udata *udata);
-struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start,
- u64 length, u64 virt, int acc,
- struct ib_udata *udata);
+struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
+ struct ib_udata *udata);
struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc);
int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
@@ -504,8 +504,8 @@ struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc)
return ERR_PTR(ret);
}
-struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt, int acc, struct ib_udata *udata)
+struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, struct ib_user_mr_attr *attr,
+ struct ib_udata *udata)
{
__be64 *pages;
int shift, n, i;
@@ -517,16 +517,16 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
pr_debug("ib_pd %p\n", pd);
- if (length == ~0ULL)
+ if (attr->length == ~0ULL)
return ERR_PTR(-EINVAL);
- if ((length + start) < start)
+ if ((attr->length + attr->start) < attr->start)
return ERR_PTR(-EINVAL);
php = to_c4iw_pd(pd);
rhp = php->rhp;
- if (mr_exceeds_hw_limits(rhp, length))
+ if (mr_exceeds_hw_limits(rhp, attr->length))
return ERR_PTR(-EINVAL);
mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
@@ -542,7 +542,8 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
mhp->rhp = rhp;
- mhp->umem = ib_umem_get(pd->device, start, length, acc);
+ mhp->umem = ib_umem_get(pd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(mhp->umem))
goto err_free_skb;
@@ -586,10 +587,10 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
mhp->attr.pdid = php->pdid;
mhp->attr.zbva = 0;
- mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
- mhp->attr.va_fbo = virt;
+ mhp->attr.perms = c4iw_ib_to_tpt_access(attr->access_flags);
+ mhp->attr.va_fbo = attr->virt_addr;
mhp->attr.page_size = shift - 12;
- mhp->attr.len = length;
+ mhp->attr.len = attr->length;
err = register_mem(rhp, php, mhp, shift);
if (err)
@@ -142,8 +142,7 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd,
void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
struct ib_udata *udata);
-struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, struct ib_user_mr_attr *attr,
struct ib_udata *udata);
int efa_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
int efa_get_port_immutable(struct ib_device *ibdev, u8 port_num,
@@ -1346,8 +1346,7 @@ static int efa_create_pbl(struct efa_dev *dev,
return 0;
}
-struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct efa_dev *dev = to_edev(ibpd->device);
@@ -1372,11 +1371,11 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
IB_ACCESS_LOCAL_WRITE |
(is_rdma_read_cap(dev) ? IB_ACCESS_REMOTE_READ : 0);
- access_flags &= ~IB_ACCESS_OPTIONAL;
- if (access_flags & ~supp_access_flags) {
+ attr->access_flags &= ~IB_ACCESS_OPTIONAL;
+ if (attr->access_flags & ~supp_access_flags) {
ibdev_dbg(&dev->ibdev,
"Unsupported access flags[%#x], supported[%#x]\n",
- access_flags, supp_access_flags);
+ attr->access_flags, supp_access_flags);
err = -EOPNOTSUPP;
goto err_out;
}
@@ -1387,7 +1386,8 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
goto err_out;
}
- mr->umem = ib_umem_get(ibpd->device, start, length, access_flags);
+ mr->umem = ib_umem_get(ibpd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(mr->umem)) {
err = PTR_ERR(mr->umem);
ibdev_dbg(&dev->ibdev,
@@ -1396,13 +1396,13 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
}
params.pd = to_epd(ibpd)->pdn;
- params.iova = virt_addr;
- params.mr_length_in_bytes = length;
- params.permissions = access_flags;
+ params.iova = attr->virt_addr;
+ params.mr_length_in_bytes = attr->length;
+ params.permissions = attr->access_flags;
pg_sz = ib_umem_find_best_pgsz(mr->umem,
dev->dev_attr.page_size_cap,
- virt_addr);
+ attr->virt_addr);
if (!pg_sz) {
err = -EOPNOTSUPP;
ibdev_dbg(&dev->ibdev, "Failed to find a suitable page size in page_size_cap %#llx\n",
@@ -1416,7 +1416,7 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
ibdev_dbg(&dev->ibdev,
"start %#llx length %#llx params.page_shift %u params.page_num %u\n",
- start, length, params.page_shift, params.page_num);
+ attr->start, attr->length, params.page_shift, params.page_num);
inline_size = ARRAY_SIZE(params.pbl.inline_pbl_array);
if (params.page_num <= inline_size) {
@@ -1441,7 +1441,7 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
mr->ibmr.lkey = result.l_key;
mr->ibmr.rkey = result.r_key;
- mr->ibmr.length = length;
+ mr->ibmr.length = attr->length;
ibdev_dbg(&dev->ibdev, "Registered mr[%d]\n", mr->ibmr.lkey);
return &mr->ibmr;
@@ -1184,11 +1184,11 @@ int hns_roce_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
void hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
struct ib_mr *hns_roce_get_dma_mr(struct ib_pd *pd, int acc);
-struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
-int hns_roce_rereg_user_mr(struct ib_mr *mr, int flags, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags, struct ib_pd *pd,
+int hns_roce_rereg_user_mr(struct ib_mr *mr, int flags,
+ struct ib_user_mr_attr *attr, struct ib_pd *pd,
struct ib_udata *udata);
struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
u32 max_num_sg);
@@ -259,8 +259,8 @@ struct ib_mr *hns_roce_get_dma_mr(struct ib_pd *pd, int acc)
return ERR_PTR(ret);
}
-struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
@@ -272,12 +272,13 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
return ERR_PTR(-ENOMEM);
mr->type = MR_TYPE_MR;
- ret = alloc_mr_key(hr_dev, mr, to_hr_pd(pd)->pdn, virt_addr, length,
- access_flags);
+ ret = alloc_mr_key(hr_dev, mr, to_hr_pd(pd)->pdn, attr->virt_addr,
+ attr->length, attr->access_flags);
if (ret)
goto err_alloc_mr;
- ret = alloc_mr_pbl(hr_dev, mr, length, udata, start, access_flags);
+ ret = alloc_mr_pbl(hr_dev, mr, attr->length, udata, attr->start,
+ attr->access_flags);
if (ret)
goto err_alloc_key;
@@ -286,7 +287,7 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
goto err_alloc_pbl;
mr->ibmr.rkey = mr->ibmr.lkey = mr->key;
- mr->ibmr.length = length;
+ mr->ibmr.length = attr->length;
return &mr->ibmr;
@@ -328,8 +329,8 @@ static int rereg_mr_trans(struct ib_mr *ibmr, int flags,
return ret;
}
-int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags, struct ib_pd *pd,
+int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
@@ -365,15 +366,16 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
if (flags & IB_MR_REREG_TRANS) {
ret = rereg_mr_trans(ibmr, flags,
- start, length,
- virt_addr, mr_access_flags,
+ attr->start, attr->length,
+ attr->virt_addr, attr->access_flags,
mailbox, pdn, udata);
if (ret)
goto free_cmd_mbox;
} else {
ret = hr_dev->hw->rereg_write_mtpt(hr_dev, mr, flags, pdn,
- mr_access_flags, virt_addr,
- length, mailbox->buf);
+ attr->access_flags,
+ attr->virt_addr,
+ attr->length, mailbox->buf);
if (ret)
goto free_cmd_mbox;
}
@@ -386,7 +388,7 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
mr->enabled = 1;
if (flags & IB_MR_REREG_ACCESS)
- mr->access = mr_access_flags;
+ mr->access = attr->access_flags;
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
@@ -1722,17 +1722,11 @@ static int i40iw_hwreg_mr(struct i40iw_device *iwdev,
/**
* i40iw_reg_user_mr - Register a user memory region
* @pd: ptr of pd
- * @start: virtual start address
- * @length: length of mr
- * @virt: virtual address
- * @acc: access of mr
+ * @attr: attributes for user mr
* @udata: user data
*/
static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
- u64 start,
- u64 length,
- u64 virt,
- int acc,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct i40iw_pd *iwpd = to_iwpd(pd);
@@ -1760,9 +1754,11 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
if (iwdev->closing)
return ERR_PTR(-ENODEV);
- if (length > I40IW_MAX_MR_SIZE)
+ if (attr->length > I40IW_MAX_MR_SIZE)
return ERR_PTR(-EINVAL);
- region = ib_umem_get(pd->device, start, length, acc);
+
+ region = ib_umem_get(pd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(region))
return (struct ib_mr *)region;
@@ -1786,15 +1782,15 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
iwmr->page_size = PAGE_SIZE;
if (req.reg_type == IW_MEMREG_TYPE_MEM)
iwmr->page_size = ib_umem_find_best_pgsz(region, SZ_4K | SZ_2M,
- virt);
+ attr->virt_addr);
- region_length = region->length + (start & (iwmr->page_size - 1));
+ region_length = region->length + (attr->start & (iwmr->page_size - 1));
pg_shift = ffs(iwmr->page_size) - 1;
pbl_depth = region_length >> pg_shift;
pbl_depth += (region_length & (iwmr->page_size - 1)) ? 1 : 0;
iwmr->length = region->length;
- iwpbl->user_base = virt;
+ iwpbl->user_base = attr->virt_addr;
palloc = &iwpbl->pble_alloc;
iwmr->type = req.reg_type;
@@ -1838,7 +1834,7 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
}
}
- access |= i40iw_get_user_access(acc);
+ access |= i40iw_get_user_access(attr->access_flags);
stag = i40iw_create_stag(iwdev);
if (!stag) {
err = -ENOMEM;
@@ -721,8 +721,8 @@ int mlx4_ib_db_map_user(struct ib_udata *udata, unsigned long virt,
struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc);
int mlx4_ib_umem_write_mtt(struct mlx4_ib_dev *dev, struct mlx4_mtt *mtt,
struct ib_umem *umem);
-struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
int mlx4_ib_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);
struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
@@ -876,8 +876,7 @@ void mlx4_ib_slave_alias_guid_event(struct mlx4_ib_dev *dev, int slave,
int mlx4_ib_steer_qp_reg(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
int is_attach);
int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
- u64 start, u64 length, u64 virt_addr,
- int mr_access_flags, struct ib_pd *pd,
+ struct ib_user_mr_attr *attr, struct ib_pd *pd,
struct ib_udata *udata);
int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev,
const struct ib_gid_attr *attr);
@@ -401,8 +401,8 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_device *device, u64 start,
return ib_umem_get(device, start, length, access_flags);
}
-struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct mlx4_ib_dev *dev = to_mdev(pd->device);
@@ -415,17 +415,19 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (!mr)
return ERR_PTR(-ENOMEM);
- mr->umem = mlx4_get_umem_mr(pd->device, start, length, access_flags);
+ mr->umem = mlx4_get_umem_mr(pd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(mr->umem)) {
err = PTR_ERR(mr->umem);
goto err_free;
}
n = ib_umem_page_count(mr->umem);
- shift = mlx4_ib_umem_calc_optimal_mtt_size(mr->umem, start, &n);
+ shift = mlx4_ib_umem_calc_optimal_mtt_size(mr->umem, attr->start, &n);
- err = mlx4_mr_alloc(dev->dev, to_mpd(pd)->pdn, virt_addr, length,
- convert_access(access_flags), n, shift, &mr->mmr);
+ err = mlx4_mr_alloc(dev->dev, to_mpd(pd)->pdn, attr->virt_addr,
+ attr->length, convert_access(attr->access_flags),
+ n, shift, &mr->mmr);
if (err)
goto err_umem;
@@ -438,7 +440,7 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
goto err_mr;
mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key;
- mr->ibmr.length = length;
+ mr->ibmr.length = attr->length;
mr->ibmr.page_size = 1U << shift;
return &mr->ibmr;
@@ -456,8 +458,7 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
}
int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
- u64 start, u64 length, u64 virt_addr,
- int mr_access_flags, struct ib_pd *pd,
+ struct ib_user_mr_attr *attr, struct ib_pd *pd,
struct ib_udata *udata)
{
struct mlx4_ib_dev *dev = to_mdev(mr->device);
@@ -484,14 +485,14 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
}
if (flags & IB_MR_REREG_ACCESS) {
- if (ib_access_writable(mr_access_flags) &&
+ if (ib_access_writable(attr->access_flags) &&
!mmr->umem->writable) {
err = -EPERM;
goto release_mpt_entry;
}
err = mlx4_mr_hw_change_access(dev->dev, *pmpt_entry,
- convert_access(mr_access_flags));
+ convert_access(attr->access_flags));
if (err)
goto release_mpt_entry;
@@ -503,8 +504,8 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr);
ib_umem_release(mmr->umem);
- mmr->umem = mlx4_get_umem_mr(mr->device, start, length,
- mr_access_flags);
+ mmr->umem = mlx4_get_umem_mr(mr->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(mmr->umem)) {
err = PTR_ERR(mmr->umem);
/* Prevent mlx4_ib_dereg_mr from free'ing invalid pointer */
@@ -515,14 +516,14 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
shift = PAGE_SHIFT;
err = mlx4_mr_rereg_mem_write(dev->dev, &mmr->mmr,
- virt_addr, length, n, shift,
- *pmpt_entry);
+ attr->virt_addr, attr->length,
+ n, shift, *pmpt_entry);
if (err) {
ib_umem_release(mmr->umem);
goto release_mpt_entry;
}
- mmr->mmr.iova = virt_addr;
- mmr->mmr.size = length;
+ mmr->mmr.iova = attr->virt_addr;
+ mmr->mmr.size = attr->length;
err = mlx4_ib_umem_write_mtt(dev, &mmr->mmr.mtt, mmr->umem);
if (err) {
@@ -537,7 +538,7 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags,
*/
err = mlx4_mr_hw_write_mpt(dev->dev, &mmr->mmr, pmpt_entry);
if (!err && flags & IB_MR_REREG_ACCESS)
- mmr->mmr.access = mr_access_flags;
+ mmr->mmr.access = attr->access_flags;
release_mpt_entry:
mlx4_mr_hw_put_mpt(dev->dev, pmpt_entry);
@@ -1154,8 +1154,8 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata);
struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc);
-struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
int mlx5_ib_advise_mr(struct ib_pd *pd,
enum ib_uverbs_advise_mr_advice advice,
@@ -1173,8 +1173,8 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd,
int access_flags);
void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *mr);
void mlx5_ib_fence_odp_mr(struct mlx5_ib_mr *mr);
-int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
- u64 length, u64 virt_addr, int access_flags,
+int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags,
+ struct ib_user_mr_attr *attr,
struct ib_pd *pd, struct ib_udata *udata);
int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
@@ -1347,8 +1347,8 @@ struct ib_mr *mlx5_ib_reg_dm_mr(struct ib_pd *pd, struct ib_dm *dm,
attr->access_flags, mode);
}
-struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct mlx5_ib_dev *dev = to_mdev(pd->device);
@@ -1365,39 +1365,41 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
return ERR_PTR(-EOPNOTSUPP);
mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n",
- start, virt_addr, length, access_flags);
+ attr->start, attr->virt_addr, attr->length, attr->access_flags);
- if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) && !start &&
- length == U64_MAX) {
- if (virt_addr != start)
+ if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) && !attr->start &&
+ attr->length == U64_MAX) {
+ if (attr->virt_addr != attr->start)
return ERR_PTR(-EINVAL);
- if (!(access_flags & IB_ACCESS_ON_DEMAND) ||
+ if (!(attr->access_flags & IB_ACCESS_ON_DEMAND) ||
!(dev->odp_caps.general_caps & IB_ODP_SUPPORT_IMPLICIT))
return ERR_PTR(-EINVAL);
- mr = mlx5_ib_alloc_implicit_mr(to_mpd(pd), udata, access_flags);
+ mr = mlx5_ib_alloc_implicit_mr(to_mpd(pd), udata,
+ attr->access_flags);
if (IS_ERR(mr))
return ERR_CAST(mr);
return &mr->ibmr;
}
- err = mr_umem_get(dev, start, length, access_flags, &umem,
+ err = mr_umem_get(dev, attr->start, attr->length,
+ attr->access_flags, &umem,
&npages, &page_shift, &ncont, &order);
-
if (err < 0)
return ERR_PTR(err);
- use_umr = mlx5_ib_can_use_umr(dev, true, access_flags);
+ use_umr = mlx5_ib_can_use_umr(dev, true, attr->access_flags);
if (order <= mr_cache_max_order(dev) && use_umr) {
- mr = alloc_mr_from_cache(pd, umem, virt_addr, length, ncont,
- page_shift, order, access_flags);
+ mr = alloc_mr_from_cache(pd, umem, attr->virt_addr,
+ attr->length, ncont, page_shift,
+ order, attr->access_flags);
if (PTR_ERR(mr) == -EAGAIN) {
mlx5_ib_dbg(dev, "cache empty for order %d\n", order);
mr = NULL;
}
} else if (!MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) {
- if (access_flags & IB_ACCESS_ON_DEMAND) {
+ if (attr->access_flags & IB_ACCESS_ON_DEMAND) {
err = -EINVAL;
pr_err("Got MR registration for ODP MR > 512MB, not supported for Connect-IB\n");
goto error;
@@ -1407,8 +1409,9 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (!mr) {
mutex_lock(&dev->slow_path_mutex);
- mr = reg_create(NULL, pd, virt_addr, length, umem, ncont,
- page_shift, access_flags, !use_umr);
+ mr = reg_create(NULL, pd, attr->virt_addr, attr->length, umem,
+ ncont, page_shift, attr->access_flags,
+ !use_umr);
mutex_unlock(&dev->slow_path_mutex);
}
@@ -1420,12 +1423,12 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
mlx5_ib_dbg(dev, "mkey 0x%x\n", mr->mmkey.key);
mr->umem = umem;
- set_mr_fields(dev, mr, npages, length, access_flags);
+ set_mr_fields(dev, mr, npages, attr->length, attr->access_flags);
if (use_umr) {
int update_xlt_flags = MLX5_IB_UPD_XLT_ENABLE;
- if (access_flags & IB_ACCESS_ON_DEMAND)
+ if (attr->access_flags & IB_ACCESS_ON_DEMAND)
update_xlt_flags |= MLX5_IB_UPD_XLT_ZAP;
err = mlx5_ib_update_xlt(mr, 0, ncont, page_shift,
@@ -1504,15 +1507,15 @@ static int rereg_umr(struct ib_pd *pd, struct mlx5_ib_mr *mr,
return err;
}
-int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
- u64 length, u64 virt_addr, int new_access_flags,
+int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags,
+ struct ib_user_mr_attr *attr,
struct ib_pd *new_pd, struct ib_udata *udata)
{
struct mlx5_ib_dev *dev = to_mdev(ib_mr->device);
struct mlx5_ib_mr *mr = to_mmr(ib_mr);
struct ib_pd *pd = (flags & IB_MR_REREG_PD) ? new_pd : ib_mr->pd;
int access_flags = flags & IB_MR_REREG_ACCESS ?
- new_access_flags :
+ attr->access_flags :
mr->access_flags;
int page_shift = 0;
int upd_flags = 0;
@@ -1523,7 +1526,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
int err;
mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n",
- start, virt_addr, length, access_flags);
+ attr->start, attr->virt_addr, attr->length, access_flags);
atomic_sub(mr->npages, &dev->mdev->priv.reg_pages);
@@ -1534,8 +1537,8 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
return -EOPNOTSUPP;
if (flags & IB_MR_REREG_TRANS) {
- addr = virt_addr;
- len = length;
+ addr = attr->virt_addr;
+ len = attr->length;
} else {
addr = mr->umem->address;
len = mr->umem->length;
@@ -842,8 +842,9 @@ static struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, int acc)
return &mr->ibmr;
}
-static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt, int acc, struct ib_udata *udata)
+static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
+ struct ib_udata *udata)
{
struct mthca_dev *dev = to_mdev(pd->device);
struct sg_dma_page_iter sg_iter;
@@ -871,7 +872,8 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (!mr)
return ERR_PTR(-ENOMEM);
- mr->umem = ib_umem_get(pd->device, start, length, acc);
+ mr->umem = ib_umem_get(pd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(mr->umem)) {
err = PTR_ERR(mr->umem);
goto err;
@@ -918,8 +920,9 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (err)
goto err_mtt;
- err = mthca_mr_alloc(dev, to_mpd(pd)->pd_num, PAGE_SHIFT, virt, length,
- convert_access(acc), mr);
+ err = mthca_mr_alloc(dev, to_mpd(pd)->pd_num, PAGE_SHIFT, attr->virt,
+ attr->length, convert_access(attr->access_flags),
+ mr);
if (err)
goto err_mtt;
@@ -850,8 +850,9 @@ static void build_user_pbes(struct ocrdma_dev *dev, struct ocrdma_mr *mr,
}
}
-struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
- u64 usr_addr, int acc, struct ib_udata *udata)
+struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd,
+ struct ib_user_mr_attr *attr,
+ struct ib_udata *udata)
{
int status = -ENOMEM;
struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
@@ -867,7 +868,9 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
mr = kzalloc(sizeof(*mr), GFP_KERNEL);
if (!mr)
return ERR_PTR(status);
- mr->umem = ib_umem_get(ibpd->device, start, len, acc);
+
+ mr->umem = ib_umem_get(ibpd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(mr->umem)) {
status = -EFAULT;
goto umem_err;
@@ -879,18 +882,18 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
mr->hwmr.pbe_size = PAGE_SIZE;
mr->hwmr.fbo = ib_umem_offset(mr->umem);
- mr->hwmr.va = usr_addr;
- mr->hwmr.len = len;
- mr->hwmr.remote_wr = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0;
- mr->hwmr.remote_rd = (acc & IB_ACCESS_REMOTE_READ) ? 1 : 0;
- mr->hwmr.local_wr = (acc & IB_ACCESS_LOCAL_WRITE) ? 1 : 0;
+ mr->hwmr.va = attr->virt_addr;
+ mr->hwmr.len = attr->length;
+ mr->hwmr.remote_wr = (attr->access_flags & IB_ACCESS_REMOTE_WRITE) ? 1 : 0;
+ mr->hwmr.remote_rd = (attr->access_flags & IB_ACCESS_REMOTE_READ) ? 1 : 0;
+ mr->hwmr.local_wr = (attr->access_flags & IB_ACCESS_LOCAL_WRITE) ? 1 : 0;
mr->hwmr.local_rd = 1;
- mr->hwmr.remote_atomic = (acc & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0;
+ mr->hwmr.remote_atomic = (attr->access_flags & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0;
status = ocrdma_build_pbl_tbl(dev, &mr->hwmr);
if (status)
goto umem_err;
build_user_pbes(dev, mr, num_pbes);
- status = ocrdma_reg_mr(dev, &mr->hwmr, pd->id, acc);
+ status = ocrdma_reg_mr(dev, &mr->hwmr, pd->id, attr->access_flags);
if (status)
goto mbx_err;
mr->ibmr.lkey = mr->hwmr.lkey;
@@ -98,8 +98,9 @@ int ocrdma_post_srq_recv(struct ib_srq *, const struct ib_recv_wr *,
int ocrdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
struct ib_mr *ocrdma_get_dma_mr(struct ib_pd *, int acc);
-struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *, u64 start, u64 length,
- u64 virt, int acc, struct ib_udata *);
+struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *,
+ struct ib_user_mr_attr *attr,
+ struct ib_udata *);
struct ib_mr *ocrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
u32 max_num_sg);
int ocrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
@@ -2833,8 +2833,8 @@ static int init_mr_info(struct qedr_dev *dev, struct mr_info *info,
return rc;
}
-struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
- u64 usr_addr, int acc, struct ib_udata *udata)
+struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, struct ib_user_mr_attr *attr,
+ struct ib_udata *udata)
{
struct qedr_dev *dev = get_qedr_dev(ibpd->device);
struct qedr_mr *mr;
@@ -2844,9 +2844,11 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
pd = get_qedr_pd(ibpd);
DP_DEBUG(dev, QEDR_MSG_MR,
"qedr_register user mr pd = %d start = %lld, len = %lld, usr_addr = %lld, acc = %d\n",
- pd->pd_id, start, len, usr_addr, acc);
+ pd->pd_id, attr->start, attr->length, attr->virt_addr,
+ attr->access_flags);
- if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE))
+ if (attr->access_flags & IB_ACCESS_REMOTE_WRITE &&
+ !(attr->access_flags & IB_ACCESS_LOCAL_WRITE))
return ERR_PTR(-EINVAL);
mr = kzalloc(sizeof(*mr), GFP_KERNEL);
@@ -2855,7 +2857,8 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
mr->type = QEDR_MR_USER;
- mr->umem = ib_umem_get(ibpd->device, start, len, acc);
+ mr->umem = ib_umem_get(ibpd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(mr->umem)) {
rc = -EFAULT;
goto err0;
@@ -2879,18 +2882,18 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
mr->hw_mr.key = 0;
mr->hw_mr.pd = pd->pd_id;
mr->hw_mr.local_read = 1;
- mr->hw_mr.local_write = (acc & IB_ACCESS_LOCAL_WRITE) ? 1 : 0;
- mr->hw_mr.remote_read = (acc & IB_ACCESS_REMOTE_READ) ? 1 : 0;
- mr->hw_mr.remote_write = (acc & IB_ACCESS_REMOTE_WRITE) ? 1 : 0;
- mr->hw_mr.remote_atomic = (acc & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0;
+ mr->hw_mr.local_write = (attr->access_flags & IB_ACCESS_LOCAL_WRITE) ? 1 : 0;
+ mr->hw_mr.remote_read = (attr->access_flags & IB_ACCESS_REMOTE_READ) ? 1 : 0;
+ mr->hw_mr.remote_write = (attr->access_flags & IB_ACCESS_REMOTE_WRITE) ? 1 : 0;
+ mr->hw_mr.remote_atomic = (attr->access_flags & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0;
mr->hw_mr.mw_bind = false;
mr->hw_mr.pbl_ptr = mr->info.pbl_table[0].pa;
mr->hw_mr.pbl_two_level = mr->info.pbl_info.two_layered;
mr->hw_mr.pbl_page_size_log = ilog2(mr->info.pbl_info.pbl_size);
mr->hw_mr.page_size_log = PAGE_SHIFT;
mr->hw_mr.fbo = ib_umem_offset(mr->umem);
- mr->hw_mr.length = len;
- mr->hw_mr.vaddr = usr_addr;
+ mr->hw_mr.length = attr->length;
+ mr->hw_mr.vaddr = attr->virt_addr;
mr->hw_mr.zbva = false;
mr->hw_mr.phy_mr = false;
mr->hw_mr.dma_mr = false;
@@ -77,8 +77,8 @@ int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
int qedr_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc);
-struct ib_mr *qedr_reg_user_mr(struct ib_pd *, u64 start, u64 length,
- u64 virt, int acc, struct ib_udata *);
+struct ib_mr *qedr_reg_user_mr(struct ib_pd *, struct ib_user_mr_attr *attr,
+ struct ib_udata *);
int qedr_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
int sg_nents, unsigned int *sg_offset);
@@ -601,22 +601,22 @@ void usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
return;
}
-struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct usnic_ib_mr *mr;
int err;
- usnic_dbg("start 0x%llx va 0x%llx length 0x%llx\n", start,
- virt_addr, length);
+ usnic_dbg("start 0x%llx va 0x%llx length 0x%llx\n", attr->start,
+ attr->virt_addr, attr->length);
mr = kzalloc(sizeof(*mr), GFP_KERNEL);
if (!mr)
return ERR_PTR(-ENOMEM);
- mr->umem = usnic_uiom_reg_get(to_upd(pd)->umem_pd, start, length,
- access_flags, 0);
+ mr->umem = usnic_uiom_reg_get(to_upd(pd)->umem_pd, attr->start,
+ attr->length, attr->access_flags, 0);
if (IS_ERR_OR_NULL(mr->umem)) {
err = mr->umem ? PTR_ERR(mr->umem) : -EFAULT;
goto err_free;
@@ -61,8 +61,8 @@ int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
int usnic_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
struct ib_udata *udata);
void usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
-struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
int usnic_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
int usnic_ib_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata);
@@ -100,16 +100,13 @@ struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc)
/**
* pvrdma_reg_user_mr - register a userspace memory region
* @pd: protection domain
- * @start: starting address
- * @length: length of region
- * @virt_addr: I/O virtual address
- * @access_flags: access flags for memory region
+ * @attr: user mr attributes
* @udata: user data
*
* @return: ib_mr pointer on success, otherwise returns an errno.
*/
-struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct pvrdma_dev *dev = to_vdev(pd->device);
@@ -121,12 +118,13 @@ struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
struct pvrdma_cmd_create_mr_resp *resp = &rsp.create_mr_resp;
int ret, npages;
- if (length == 0 || length > dev->dsr->caps.max_mr_size) {
+ if (attr->length == 0 || attr->length > dev->dsr->caps.max_mr_size) {
dev_warn(&dev->pdev->dev, "invalid mem region length\n");
return ERR_PTR(-EINVAL);
}
- umem = ib_umem_get(pd->device, start, length, access_flags);
+ umem = ib_umem_get(pd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(umem)) {
dev_warn(&dev->pdev->dev,
"could not get umem for mem region\n");
@@ -147,8 +145,8 @@ struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
goto err_umem;
}
- mr->mmr.iova = virt_addr;
- mr->mmr.size = length;
+ mr->mmr.iova = attr->virt_addr;
+ mr->mmr.size = attr->length;
mr->umem = umem;
ret = pvrdma_page_dir_init(dev, &mr->pdir, npages, false);
@@ -164,10 +162,10 @@ struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
memset(cmd, 0, sizeof(*cmd));
cmd->hdr.cmd = PVRDMA_CMD_CREATE_MR;
- cmd->start = start;
- cmd->length = length;
+ cmd->start = attr->start;
+ cmd->length = attr->length;
cmd->pd_handle = to_vpd(pd)->pd_handle;
- cmd->access_flags = access_flags;
+ cmd->access_flags = attr->access_flags;
cmd->nchunks = npages;
cmd->pdir_dma = mr->pdir.dir_dma;
@@ -401,8 +401,8 @@ int pvrdma_modify_port(struct ib_device *ibdev, u8 port,
int pvrdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
void pvrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc);
-struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int access_flags,
+struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
int pvrdma_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);
struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
@@ -369,15 +369,13 @@ struct ib_mr *rvt_get_dma_mr(struct ib_pd *pd, int acc)
/**
* rvt_reg_user_mr - register a userspace memory region
* @pd: protection domain for this memory region
- * @start: starting userspace address
- * @length: length of region to register
- * @mr_access_flags: access flags for this memory region
+ * @attr: userspace memory region attributes
* @udata: unused by the driver
*
* Return: the memory region on success, otherwise returns an errno.
*/
-struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags,
+struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata)
{
struct rvt_mr *mr;
@@ -386,10 +384,11 @@ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
int n, m;
struct ib_mr *ret;
- if (length == 0)
+ if (attr->length == 0)
return ERR_PTR(-EINVAL);
- umem = ib_umem_get(pd->device, start, length, mr_access_flags);
+ umem = ib_umem_get(pd->device, attr->start, attr->length,
+ attr->access_flags);
if (IS_ERR(umem))
return (void *)umem;
@@ -401,11 +400,11 @@ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
goto bail_umem;
}
- mr->mr.user_base = start;
- mr->mr.iova = virt_addr;
- mr->mr.length = length;
+ mr->mr.user_base = attr->start;
+ mr->mr.iova = attr->virt_addr;
+ mr->mr.length = attr->length;
mr->mr.offset = ib_umem_offset(umem);
- mr->mr.access_flags = mr_access_flags;
+ mr->mr.access_flags = attr->access_flags;
mr->umem = umem;
mr->mr.page_shift = PAGE_SHIFT;
@@ -66,8 +66,8 @@ static inline struct rvt_mr *to_imr(struct ib_mr *ibmr)
/* Mem Regions */
struct ib_mr *rvt_get_dma_mr(struct ib_pd *pd, int acc);
-struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags,
+struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
int rvt_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
@@ -904,10 +904,8 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access)
}
static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
- u64 start,
- u64 length,
- u64 iova,
- int access, struct ib_udata *udata)
+ struct ib_user_mr_attr *attr,
+ struct ib_udata *udata)
{
int err;
struct rxe_dev *rxe = to_rdev(ibpd->device);
@@ -924,8 +922,8 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
rxe_add_ref(pd);
- err = rxe_mem_init_user(pd, start, length, iova,
- access, udata, mr);
+ err = rxe_mem_init_user(pd, attr->start, attr->length, attr->virt_addr,
+ attr->access_flags, udata, mr);
if (err)
goto err3;
@@ -1262,14 +1262,12 @@ int siw_dereg_mr(struct ib_mr *base_mr, struct ib_udata *udata)
* Register Memory Region.
*
* @pd: Protection Domain
- * @start: starting address of MR (virtual address)
- * @len: len of MR
- * @rnic_va: not used by siw
- * @rights: MR access rights
+ * @attr: user space MR attributes
* @udata: user buffer to communicate STag and Key.
*/
-struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
- u64 rnic_va, int rights, struct ib_udata *udata)
+struct ib_mr *siw_reg_user_mr(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
+ struct ib_udata *udata)
{
struct siw_mr *mr = NULL;
struct siw_umem *umem = NULL;
@@ -1280,21 +1278,23 @@ struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
int rv;
siw_dbg_pd(pd, "start: 0x%pK, va: 0x%pK, len: %llu\n",
- (void *)(uintptr_t)start, (void *)(uintptr_t)rnic_va,
- (unsigned long long)len);
+ (void *)(uintptr_t)attr->start,
+ (void *)(uintptr_t)attr->virt_addr,
+ (unsigned long long)attr->length);
if (atomic_inc_return(&sdev->num_mr) > SIW_MAX_MR) {
siw_dbg_pd(pd, "too many mr's\n");
rv = -ENOMEM;
goto err_out;
}
- if (!len) {
+ if (!attr->length) {
rv = -EINVAL;
goto err_out;
}
if (mem_limit != RLIM_INFINITY) {
unsigned long num_pages =
- (PAGE_ALIGN(len + (start & ~PAGE_MASK))) >> PAGE_SHIFT;
+ (PAGE_ALIGN(attr->length + (attr->start & ~PAGE_MASK)))
+ >> PAGE_SHIFT;
mem_limit >>= PAGE_SHIFT;
if (num_pages > mem_limit - current->mm->locked_vm) {
@@ -1305,7 +1305,8 @@ struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
goto err_out;
}
}
- umem = siw_umem_get(start, len, ib_access_writable(rights));
+ umem = siw_umem_get(attr->start, attr->length,
+ ib_access_writable(attr->access_flags));
if (IS_ERR(umem)) {
rv = PTR_ERR(umem);
siw_dbg_pd(pd, "getting user memory failed: %d\n", rv);
@@ -1317,7 +1318,8 @@ struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
rv = -ENOMEM;
goto err_out;
}
- rv = siw_mr_add_mem(mr, pd, umem, start, len, rights);
+ rv = siw_mr_add_mem(mr, pd, umem, attr->start, attr->length,
+ attr->access_flags);
if (rv)
goto err_out;
@@ -65,8 +65,9 @@ int siw_post_receive(struct ib_qp *base_qp, const struct ib_recv_wr *wr,
void siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata);
int siw_poll_cq(struct ib_cq *base_cq, int num_entries, struct ib_wc *wc);
int siw_req_notify_cq(struct ib_cq *base_cq, enum ib_cq_notify_flags flags);
-struct ib_mr *siw_reg_user_mr(struct ib_pd *base_pd, u64 start, u64 len,
- u64 rnic_va, int rights, struct ib_udata *udata);
+struct ib_mr *siw_reg_user_mr(struct ib_pd *base_pd,
+ struct ib_user_mr_attr *attr,
+ struct ib_udata *udata);
struct ib_mr *siw_alloc_mr(struct ib_pd *base_pd, enum ib_mr_type mr_type,
u32 max_sge);
struct ib_mr *siw_get_dma_mr(struct ib_pd *base_pd, int rights);
@@ -2,7 +2,7 @@
/*
* Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004 Infinicon Corporation. All rights reserved.
- * Copyright (c) 2004 Intel Corporation. All rights reserved.
+ * Copyright (c) 2004, 2020 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
@@ -372,6 +372,14 @@ struct ib_dm_alloc_attr {
u32 flags;
};
+struct ib_user_mr_attr {
+ u64 start;
+ u64 length;
+ u64 virt_addr;
+ u32 fd;
+ u32 access_flags;
+};
+
struct ib_device_attr {
u64 fw_ver;
__be64 sys_image_guid;
@@ -1431,11 +1439,12 @@ enum ib_access_flags {
IB_ZERO_BASED = IB_UVERBS_ACCESS_ZERO_BASED,
IB_ACCESS_ON_DEMAND = IB_UVERBS_ACCESS_ON_DEMAND,
IB_ACCESS_HUGETLB = IB_UVERBS_ACCESS_HUGETLB,
+ IB_ACCESS_DMABUF = IB_UVERBS_ACCESS_DMABUF,
IB_ACCESS_RELAXED_ORDERING = IB_UVERBS_ACCESS_RELAXED_ORDERING,
IB_ACCESS_OPTIONAL = IB_UVERBS_ACCESS_OPTIONAL_RANGE,
IB_ACCESS_SUPPORTED =
- ((IB_ACCESS_HUGETLB << 1) - 1) | IB_ACCESS_OPTIONAL,
+ ((IB_ACCESS_DMABUF << 1) - 1) | IB_ACCESS_OPTIONAL,
};
/*
@@ -2442,11 +2451,11 @@ struct ib_device_ops {
void (*destroy_cq)(struct ib_cq *cq, struct ib_udata *udata);
int (*resize_cq)(struct ib_cq *cq, int cqe, struct ib_udata *udata);
struct ib_mr *(*get_dma_mr)(struct ib_pd *pd, int mr_access_flags);
- struct ib_mr *(*reg_user_mr)(struct ib_pd *pd, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags,
+ struct ib_mr *(*reg_user_mr)(struct ib_pd *pd,
+ struct ib_user_mr_attr *attr,
struct ib_udata *udata);
- int (*rereg_user_mr)(struct ib_mr *mr, int flags, u64 start, u64 length,
- u64 virt_addr, int mr_access_flags,
+ int (*rereg_user_mr)(struct ib_mr *mr, int flags,
+ struct ib_user_mr_attr *attr,
struct ib_pd *pd, struct ib_udata *udata);
int (*dereg_mr)(struct ib_mr *mr, struct ib_udata *udata);
struct ib_mr *(*alloc_mr)(struct ib_pd *pd, enum ib_mr_type mr_type,
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR Linux-OpenIB) */
/*
* Copyright (c) 2017-2018, Mellanox Technologies inc. All rights reserved.
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -57,6 +58,7 @@ enum ib_uverbs_access_flags {
IB_UVERBS_ACCESS_ZERO_BASED = 1 << 5,
IB_UVERBS_ACCESS_ON_DEMAND = 1 << 6,
IB_UVERBS_ACCESS_HUGETLB = 1 << 7,
+ IB_UVERBS_ACCESS_DMABUF = 1 << 8,
IB_UVERBS_ACCESS_RELAXED_ORDERING = IB_UVERBS_ACCESS_OPTIONAL_FIRST,
IB_UVERBS_ACCESS_OPTIONAL_RANGE =