RDMA/mlx5: Check enabled UCAPs when creating ucontext
Verify that the enabled UCAPs are supported by the device before creating the ucontext. If supported, create the ucontext with the associated capabilities. Store the privileged ucontext UID on creation and remove it when destroying the privileged ucontext. This allows the command interface to recognize privileged commands through its UID. Signed-off-by: Chiara Meiohas <cmeiohas@nvidia.com> Link: https://patch.msgid.link/8b180583a207cb30deb7a2967934079749cdcc44.1741261611.git.leon@kernel.org Reviewed-by: Yishai Hadas <yishaih@nvidia.com> Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
committed by
Leon Romanovsky
parent
fe9d7822ba
commit
17ade53663
@@ -13,6 +13,7 @@
|
||||
#include <rdma/uverbs_std_types.h>
|
||||
#include <linux/mlx5/driver.h>
|
||||
#include <linux/mlx5/fs.h>
|
||||
#include <rdma/ib_ucaps.h>
|
||||
#include "mlx5_ib.h"
|
||||
#include "devx.h"
|
||||
#include "qp.h"
|
||||
@@ -122,7 +123,27 @@ devx_ufile2uctx(const struct uverbs_attr_bundle *attrs)
|
||||
return to_mucontext(ib_uverbs_get_ucontext(attrs));
|
||||
}
|
||||
|
||||
int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user)
|
||||
static int set_uctx_ucaps(struct mlx5_ib_dev *dev, u64 req_ucaps, u32 *cap)
|
||||
{
|
||||
if (UCAP_ENABLED(req_ucaps, RDMA_UCAP_MLX5_CTRL_LOCAL)) {
|
||||
if (MLX5_CAP_GEN(dev->mdev, uctx_cap) & MLX5_UCTX_CAP_RDMA_CTRL)
|
||||
*cap |= MLX5_UCTX_CAP_RDMA_CTRL;
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (UCAP_ENABLED(req_ucaps, RDMA_UCAP_MLX5_CTRL_OTHER_VHCA)) {
|
||||
if (MLX5_CAP_GEN(dev->mdev, uctx_cap) &
|
||||
MLX5_UCTX_CAP_RDMA_CTRL_OTHER_VHCA)
|
||||
*cap |= MLX5_UCTX_CAP_RDMA_CTRL_OTHER_VHCA;
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user, u64 req_ucaps)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(create_uctx_in)] = {};
|
||||
u32 out[MLX5_ST_SZ_DW(create_uctx_out)] = {};
|
||||
@@ -146,6 +167,12 @@ int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user)
|
||||
capable(CAP_SYS_RAWIO))
|
||||
cap |= MLX5_UCTX_CAP_INTERNAL_DEV_RES;
|
||||
|
||||
if (req_ucaps) {
|
||||
err = set_uctx_ucaps(dev, req_ucaps, &cap);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
MLX5_SET(create_uctx_in, in, opcode, MLX5_CMD_OP_CREATE_UCTX);
|
||||
MLX5_SET(uctx, uctx, cap, cap);
|
||||
|
||||
@@ -2575,7 +2602,7 @@ int mlx5_ib_devx_init(struct mlx5_ib_dev *dev)
|
||||
struct mlx5_devx_event_table *table = &dev->devx_event_table;
|
||||
int uid;
|
||||
|
||||
uid = mlx5_ib_devx_create(dev, false);
|
||||
uid = mlx5_ib_devx_create(dev, false, 0);
|
||||
if (uid > 0) {
|
||||
dev->devx_whitelist_uid = uid;
|
||||
xa_init(&table->event_xa);
|
||||
|
||||
@@ -24,13 +24,14 @@ struct devx_obj {
|
||||
struct list_head event_sub; /* holds devx_event_subscription entries */
|
||||
};
|
||||
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
|
||||
int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user);
|
||||
int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user, u64 req_ucaps);
|
||||
void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid);
|
||||
int mlx5_ib_devx_init(struct mlx5_ib_dev *dev);
|
||||
void mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev);
|
||||
void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile);
|
||||
#else
|
||||
static inline int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user)
|
||||
static inline int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user,
|
||||
u64 req_ucaps)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -1935,6 +1935,12 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool uctx_rdma_ctrl_is_enabled(u64 enabled_caps)
|
||||
{
|
||||
return UCAP_ENABLED(enabled_caps, RDMA_UCAP_MLX5_CTRL_LOCAL) ||
|
||||
UCAP_ENABLED(enabled_caps, RDMA_UCAP_MLX5_CTRL_OTHER_VHCA);
|
||||
}
|
||||
|
||||
static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
@@ -1977,10 +1983,17 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
|
||||
return -EINVAL;
|
||||
|
||||
if (req.flags & MLX5_IB_ALLOC_UCTX_DEVX) {
|
||||
err = mlx5_ib_devx_create(dev, true);
|
||||
err = mlx5_ib_devx_create(dev, true, uctx->enabled_caps);
|
||||
if (err < 0)
|
||||
goto out_ctx;
|
||||
context->devx_uid = err;
|
||||
|
||||
if (uctx_rdma_ctrl_is_enabled(uctx->enabled_caps)) {
|
||||
err = mlx5_cmd_add_privileged_uid(dev->mdev,
|
||||
context->devx_uid);
|
||||
if (err)
|
||||
goto out_devx;
|
||||
}
|
||||
}
|
||||
|
||||
lib_uar_4k = req.lib_caps & MLX5_LIB_CAP_4K_UAR;
|
||||
@@ -1995,7 +2008,7 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
|
||||
/* updates req->total_num_bfregs */
|
||||
err = calc_total_bfregs(dev, lib_uar_4k, &req, bfregi);
|
||||
if (err)
|
||||
goto out_devx;
|
||||
goto out_ucap;
|
||||
|
||||
mutex_init(&bfregi->lock);
|
||||
bfregi->lib_uar_4k = lib_uar_4k;
|
||||
@@ -2003,7 +2016,7 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
|
||||
GFP_KERNEL);
|
||||
if (!bfregi->count) {
|
||||
err = -ENOMEM;
|
||||
goto out_devx;
|
||||
goto out_ucap;
|
||||
}
|
||||
|
||||
bfregi->sys_pages = kcalloc(bfregi->num_sys_pages,
|
||||
@@ -2067,6 +2080,11 @@ out_sys_pages:
|
||||
out_count:
|
||||
kfree(bfregi->count);
|
||||
|
||||
out_ucap:
|
||||
if (req.flags & MLX5_IB_ALLOC_UCTX_DEVX &&
|
||||
uctx_rdma_ctrl_is_enabled(uctx->enabled_caps))
|
||||
mlx5_cmd_remove_privileged_uid(dev->mdev, context->devx_uid);
|
||||
|
||||
out_devx:
|
||||
if (req.flags & MLX5_IB_ALLOC_UCTX_DEVX)
|
||||
mlx5_ib_devx_destroy(dev, context->devx_uid);
|
||||
@@ -2111,8 +2129,12 @@ static void mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
|
||||
kfree(bfregi->sys_pages);
|
||||
kfree(bfregi->count);
|
||||
|
||||
if (context->devx_uid)
|
||||
if (context->devx_uid) {
|
||||
if (uctx_rdma_ctrl_is_enabled(ibcontext->enabled_caps))
|
||||
mlx5_cmd_remove_privileged_uid(dev->mdev,
|
||||
context->devx_uid);
|
||||
mlx5_ib_devx_destroy(dev, context->devx_uid);
|
||||
}
|
||||
}
|
||||
|
||||
static phys_addr_t uar_index2pfn(struct mlx5_ib_dev *dev,
|
||||
|
||||
Reference in New Issue
Block a user