RDMA/uverbs: Check ODP in ib_check_mr_access() as well
authorJason Gunthorpe <jgg@nvidia.com>
Mon, 30 Nov 2020 07:58:36 +0000 (09:58 +0200)
committerJason Gunthorpe <jgg@nvidia.com>
Mon, 7 Dec 2020 18:06:23 +0000 (14:06 -0400)
No reason only one caller checks this. This properly blocks ODP
from the rereg flow if the device does not support ODP.

Link: https://lore.kernel.org/r/20201130075839.278575-3-leon@kernel.org
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_std_types_mr.c
drivers/infiniband/hw/mlx5/devx.c
include/rdma/ib_verbs.h

index 143a0e33fe52289d9331e5f1013c6a804cd5c2bd..817b25045acdc0ae3fa1a9d4b28d7f0834af1cde 100644 (file)
@@ -709,29 +709,20 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
        if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
                return -EINVAL;
 
-       ret = ib_check_mr_access(cmd.access_flags);
-       if (ret)
-               return ret;
-
        uobj = uobj_alloc(UVERBS_OBJECT_MR, attrs, &ib_dev);
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
 
+       ret = ib_check_mr_access(ib_dev, cmd.access_flags);
+       if (ret)
+               goto err_free;
+
        pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs);
        if (!pd) {
                ret = -EINVAL;
                goto err_free;
        }
 
-       if (cmd.access_flags & IB_ACCESS_ON_DEMAND) {
-               if (!(pd->device->attrs.device_cap_flags &
-                     IB_DEVICE_ON_DEMAND_PAGING)) {
-                       pr_debug("ODP support not available\n");
-                       ret = -EINVAL;
-                       goto err_put;
-               }
-       }
-
        mr = pd->device->ops.reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va,
                                         cmd.access_flags,
                                         &attrs->driver_udata);
@@ -805,7 +796,7 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
        }
 
        if (cmd.flags & IB_MR_REREG_ACCESS) {
-               ret = ib_check_mr_access(cmd.access_flags);
+               ret = ib_check_mr_access(mr->device, cmd.access_flags);
                if (ret)
                        goto put_uobjs;
        }
index dc58564417292a55aefd78f013cb9d7979975931..dd4e76b26c745960a7ec09221a0a5134d1748f2e 100644 (file)
@@ -115,7 +115,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)(
        if (!(attr.access_flags & IB_ZERO_BASED))
                return -EINVAL;
 
-       ret = ib_check_mr_access(attr.access_flags);
+       ret = ib_check_mr_access(ib_dev, attr.access_flags);
        if (ret)
                return ret;
 
index ad0173f62c0e955c8a0b4e53fe390e79ca3261e5..819c142857d650fcc93711722bed7ad6721c8605 100644 (file)
@@ -2068,7 +2068,7 @@ static int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext,
        if (err)
                return err;
 
-       err = ib_check_mr_access(access);
+       err = ib_check_mr_access(&dev->ib_dev, access);
        if (err)
                return err;
 
index 7bee8abae35cf4c53426e566bba76141d83d1bfb..4fcbc6d3d0e00f96caed03172e4d5d10d7d96f65 100644 (file)
@@ -4183,7 +4183,8 @@ struct ib_xrcd *ib_alloc_xrcd_user(struct ib_device *device,
                                   struct inode *inode, struct ib_udata *udata);
 int ib_dealloc_xrcd_user(struct ib_xrcd *xrcd, struct ib_udata *udata);
 
-static inline int ib_check_mr_access(int flags)
+static inline int ib_check_mr_access(struct ib_device *ib_dev,
+                                    unsigned int flags)
 {
        /*
         * Local write permission is required if remote write or
@@ -4196,6 +4197,9 @@ static inline int ib_check_mr_access(int flags)
        if (flags & ~IB_ACCESS_SUPPORTED)
                return -EINVAL;
 
+       if (flags & IB_ACCESS_ON_DEMAND &&
+           !(ib_dev->attrs.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING))
+               return -EINVAL;
        return 0;
 }