mlx4: Map core_clock page to user space only when allowed
Currently when we map the hca_core_clock page to the user space, there are vulnerable registers, one of which is semaphore, on this page as well. If user read the wrong offset, it can modify the above semaphore and hang the device. Hence, mapping the hca_core_clock page to the user space only when user required it specifically. After this patch, mlx4 core_clock won't be mapped to user space by default. Oppose to current state, where mlx4 core_clock is always mapped to user space. MFC after: 1 week Reviewed by: kib Sponsored by: Mellanox Technologies // NVIDIA Networking
This commit is contained in:
parent
c8d16d1e08
commit
c8301cbb0f
sys/dev/mlx4
@ -624,6 +624,7 @@ struct mlx4_caps {
|
||||
u32 dmfs_high_rate_qpn_range;
|
||||
u32 vf_caps;
|
||||
struct mlx4_rate_limit_caps rl_caps;
|
||||
bool map_clock_to_user;
|
||||
};
|
||||
|
||||
struct mlx4_buf_list {
|
||||
|
@ -129,6 +129,7 @@ struct mlx4_dev_cap {
|
||||
u32 dmfs_high_rate_qpn_range;
|
||||
struct mlx4_rate_limit_caps rl_caps;
|
||||
struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1];
|
||||
bool map_clock_to_user;
|
||||
};
|
||||
|
||||
struct mlx4_func_cap {
|
||||
|
@ -820,6 +820,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
||||
#define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0
|
||||
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8
|
||||
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac
|
||||
#define QUERY_DEV_CAP_MAP_CLOCK_TO_USER 0xc1
|
||||
#define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc
|
||||
#define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0
|
||||
#define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2
|
||||
@ -838,6 +839,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
||||
|
||||
if (mlx4_is_mfunc(dev))
|
||||
disable_unsupported_roce_caps(outbox);
|
||||
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAP_CLOCK_TO_USER);
|
||||
dev_cap->map_clock_to_user = field & 0x80;
|
||||
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET);
|
||||
dev_cap->reserved_qps = 1 << (field & 0xf);
|
||||
MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET);
|
||||
|
@ -386,6 +386,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
|
||||
}
|
||||
}
|
||||
|
||||
dev->caps.map_clock_to_user = dev_cap->map_clock_to_user;
|
||||
dev->caps.uar_page_size = PAGE_SIZE;
|
||||
dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE;
|
||||
dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay;
|
||||
@ -1872,6 +1873,11 @@ int mlx4_get_internal_clock_params(struct mlx4_dev *dev,
|
||||
if (mlx4_is_slave(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (!dev->caps.map_clock_to_user) {
|
||||
mlx4_dbg(dev, "Map clock to user is not supported.\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (!params)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -560,12 +560,9 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
|
||||
props->hca_core_clock = dev->dev->caps.hca_core_clock * 1000UL;
|
||||
props->timestamp_mask = 0xFFFFFFFFFFFFULL;
|
||||
|
||||
if (!mlx4_is_slave(dev->dev))
|
||||
err = mlx4_get_internal_clock_params(dev->dev, &clock_params);
|
||||
|
||||
if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) {
|
||||
resp.response_length += sizeof(resp.hca_core_clock_offset);
|
||||
if (!err && !mlx4_is_slave(dev->dev)) {
|
||||
if (!mlx4_get_internal_clock_params(dev->dev, &clock_params)) {
|
||||
resp.comp_mask |= QUERY_DEVICE_RESP_MASK_TIMESTAMP;
|
||||
resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user