Skip to content

Commit 404e5a1

Browse files
shayshyijgunthorpe
authored andcommitted
RDMA/mlx4: Do not map the core_clock page to user space unless enabled
Currently when mlx4 maps the hca_core_clock page to the user space there are read-modifiable registers, one of which is semaphore, on this page as well as the clock counter. If user reads the wrong offset, it can modify the semaphore and hang the device. Do not map the hca_core_clock page to the user space unless the device has been put in a backwards compatibility mode to support this feature. After this patch, mlx4 core_clock won't be mapped to user space on the majority of existing devices and the uverbs device time feature in ibv_query_rt_values_ex() will be disabled. Fixes: 52033cf ("IB/mlx4: Add mmap call to map the hardware clock") Link: https://lore.kernel.org/r/9632304e0d6790af84b3b706d8c18732bc0d5e27.1622726305.git.leonro@nvidia.com Signed-off-by: Shay Drory <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent a0ffb4c commit 404e5a1

File tree

5 files changed

+12
-4
lines changed

5 files changed

+12
-4
lines changed

drivers/infiniband/hw/mlx4/main.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,12 +581,9 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
581581
props->cq_caps.max_cq_moderation_count = MLX4_MAX_CQ_COUNT;
582582
props->cq_caps.max_cq_moderation_period = MLX4_MAX_CQ_PERIOD;
583583

584-
if (!mlx4_is_slave(dev->dev))
585-
err = mlx4_get_internal_clock_params(dev->dev, &clock_params);
586-
587584
if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) {
588585
resp.response_length += sizeof(resp.hca_core_clock_offset);
589-
if (!err && !mlx4_is_slave(dev->dev)) {
586+
if (!mlx4_get_internal_clock_params(dev->dev, &clock_params)) {
590587
resp.comp_mask |= MLX4_IB_QUERY_DEV_RESP_MASK_CORE_CLOCK_OFFSET;
591588
resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE;
592589
}

drivers/net/ethernet/mellanox/mlx4/fw.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
823823
#define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0
824824
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8
825825
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac
826+
#define QUERY_DEV_CAP_MAP_CLOCK_TO_USER 0xc1
826827
#define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc
827828
#define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0
828829
#define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2
@@ -841,6 +842,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
841842

842843
if (mlx4_is_mfunc(dev))
843844
disable_unsupported_roce_caps(outbox);
845+
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAP_CLOCK_TO_USER);
846+
dev_cap->map_clock_to_user = field & 0x80;
844847
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET);
845848
dev_cap->reserved_qps = 1 << (field & 0xf);
846849
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET);

drivers/net/ethernet/mellanox/mlx4/fw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ struct mlx4_dev_cap {
131131
u32 health_buffer_addrs;
132132
struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1];
133133
bool wol_port[MLX4_MAX_PORTS + 1];
134+
bool map_clock_to_user;
134135
};
135136

136137
struct mlx4_func_cap {

drivers/net/ethernet/mellanox/mlx4/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
498498
}
499499
}
500500

501+
dev->caps.map_clock_to_user = dev_cap->map_clock_to_user;
501502
dev->caps.uar_page_size = PAGE_SIZE;
502503
dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE;
503504
dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay;
@@ -1948,6 +1949,11 @@ int mlx4_get_internal_clock_params(struct mlx4_dev *dev,
19481949
if (mlx4_is_slave(dev))
19491950
return -EOPNOTSUPP;
19501951

1952+
if (!dev->caps.map_clock_to_user) {
1953+
mlx4_dbg(dev, "Map clock to user is not supported.\n");
1954+
return -EOPNOTSUPP;
1955+
}
1956+
19511957
if (!params)
19521958
return -EINVAL;
19531959

include/linux/mlx4/device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ struct mlx4_caps {
630630
bool wol_port[MLX4_MAX_PORTS + 1];
631631
struct mlx4_rate_limit_caps rl_caps;
632632
u32 health_buffer_addrs;
633+
bool map_clock_to_user;
633634
};
634635

635636
struct mlx4_buf_list {

0 commit comments

Comments
 (0)