Skip to content

Commit 7c043e9

Browse files
yishaihjgunthorpe
authored andcommitted
IB/mlx5: Add support for DEVX query UAR
Return a device UAR index for a given user index via the DEVX interface. Security note: The hardware protection mechanism works like this: Each device object that is subject to UAR doorbells (QP/SQ/CQ) gets a UAR ID (called uar_page in the device specification manual) upon its creation. Then upon doorbell, hardware fetches the object context for which the doorbell was rang, and validates that the UAR through which the DB was rang matches the UAR ID of the object. If no match the doorbell is silently ignored by the hardware. Of course, the user cannot ring a doorbell on a UAR that was not mapped to it. Now in devx, as the devx kernel does not manipulate the QP/SQ/CQ command mailboxes (except tagging them with UID), we expose to the user its UAR ID, so it can embed it in these objects in the expected specification format. So the only thing the user can do is hurt itself by creating a QP/SQ/CQ with a UAR ID other than his, and then in this case other users may ring a doorbell on its objects. The consequence of that will be that another user can schedule a QP/SQ of the buggy user for execution (just insert it to the hardware schedule queue or arm its CQ for event generation), no further harm is expected. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
1 parent e662e14 commit 7c043e9

File tree

4 files changed

+67
-4
lines changed

4 files changed

+67
-4
lines changed

drivers/infiniband/hw/mlx5/devx.c

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,50 @@ static bool devx_is_general_cmd(void *in)
373373
}
374374
}
375375

376+
/*
377+
*Security note:
378+
* The hardware protection mechanism works like this: Each device object that
379+
* is subject to UAR doorbells (QP/SQ/CQ) gets a UAR ID (called uar_page in
380+
* the device specification manual) upon its creation. Then upon doorbell,
381+
* hardware fetches the object context for which the doorbell was rang, and
382+
* validates that the UAR through which the DB was rang matches the UAR ID
383+
* of the object.
384+
* If no match the doorbell is silently ignored by the hardware. Of course,
385+
* the user cannot ring a doorbell on a UAR that was not mapped to it.
386+
* Now in devx, as the devx kernel does not manipulate the QP/SQ/CQ command
387+
* mailboxes (except tagging them with UID), we expose to the user its UAR
388+
* ID, so it can embed it in these objects in the expected specification
389+
* format. So the only thing the user can do is hurt itself by creating a
390+
* QP/SQ/CQ with a UAR ID other than his, and then in this case other users
391+
* may ring a doorbell on its objects.
392+
* The consequence of that will be that another user can schedule a QP/SQ
393+
* of the buggy user for execution (just insert it to the hardware schedule
394+
* queue or arm its CQ for event generation), no further harm is expected.
395+
*/
396+
static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_UAR)(struct ib_device *ib_dev,
397+
struct ib_uverbs_file *file,
398+
struct uverbs_attr_bundle *attrs)
399+
{
400+
struct mlx5_ib_ucontext *c = devx_ufile2uctx(file);
401+
u32 user_idx;
402+
s32 dev_idx;
403+
404+
if (uverbs_copy_from(&user_idx, attrs,
405+
MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX))
406+
return -EFAULT;
407+
408+
dev_idx = bfregn_to_uar_index(to_mdev(ib_dev),
409+
&c->bfregi, user_idx, true);
410+
if (dev_idx < 0)
411+
return dev_idx;
412+
413+
if (uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX,
414+
&dev_idx, sizeof(dev_idx)))
415+
return -EFAULT;
416+
417+
return 0;
418+
}
419+
376420
static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)(struct ib_device *ib_dev,
377421
struct ib_uverbs_file *file,
378422
struct uverbs_attr_bundle *attrs)
@@ -744,6 +788,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUERY)(struct ib_device *ib_de
744788
return err;
745789
}
746790

791+
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR,
792+
&UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX, UVERBS_ATTR_TYPE(u32),
793+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
794+
&UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, UVERBS_ATTR_TYPE(u32),
795+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
796+
747797
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OTHER,
748798
&UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
749799
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
@@ -808,7 +858,8 @@ static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY,
808858
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
809859

810860
static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX,
811-
&UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER));
861+
&UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER),
862+
&UVERBS_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR));
812863

813864
static DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ,
814865
&UVERBS_TYPE_ALLOC_IDR(0, devx_obj_cleanup),

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,4 +1329,7 @@ static inline int get_num_static_uars(struct mlx5_ib_dev *dev,
13291329
unsigned long mlx5_ib_get_xlt_emergency_page(void);
13301330
void mlx5_ib_put_xlt_emergency_page(void);
13311331

1332+
int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
1333+
struct mlx5_bfreg_info *bfregi, int bfregn,
1334+
bool dyn_bfreg);
13321335
#endif /* MLX5_IB_H */

drivers/infiniband/hw/mlx5/qp.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -641,9 +641,9 @@ static void mlx5_ib_lock_cqs(struct mlx5_ib_cq *send_cq,
641641
static void mlx5_ib_unlock_cqs(struct mlx5_ib_cq *send_cq,
642642
struct mlx5_ib_cq *recv_cq);
643643

644-
static int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
645-
struct mlx5_bfreg_info *bfregi, int bfregn,
646-
bool dyn_bfreg)
644+
int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
645+
struct mlx5_bfreg_info *bfregi, int bfregn,
646+
bool dyn_bfreg)
647647
{
648648
int bfregs_per_sys_page;
649649
int index_of_sys_page;
@@ -653,6 +653,9 @@ static int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
653653
MLX5_NON_FP_BFREGS_PER_UAR;
654654
index_of_sys_page = bfregn / bfregs_per_sys_page;
655655

656+
if (index_of_sys_page >= bfregi->num_sys_pages)
657+
return -EINVAL;
658+
656659
if (dyn_bfreg) {
657660
index_of_sys_page += bfregi->num_static_sys_pages;
658661
if (bfregn > bfregi->num_dyn_bfregs ||

include/uapi/rdma/mlx5_user_ioctl_cmds.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum mlx5_ib_alloc_dm_attrs {
4747

4848
enum mlx5_ib_devx_methods {
4949
MLX5_IB_METHOD_DEVX_OTHER = (1U << UVERBS_ID_NS_SHIFT),
50+
MLX5_IB_METHOD_DEVX_QUERY_UAR,
5051
};
5152

5253
enum mlx5_ib_devx_other_attrs {
@@ -60,6 +61,11 @@ enum mlx5_ib_devx_obj_create_attrs {
6061
MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT,
6162
};
6263

64+
enum mlx5_ib_devx_query_uar_attrs {
65+
MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX = (1U << UVERBS_ID_NS_SHIFT),
66+
MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX,
67+
};
68+
6369
enum mlx5_ib_devx_obj_destroy_attrs {
6470
MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
6571
};

0 commit comments

Comments
 (0)