mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
drm/amdkfd: Check bounds on CRIU restore queue type and mqd size
We weren't checking whether the values provided in the private data in kfd CRIU restore were within bounds. For queue type, add a KFD_QUEUE_TYPE_MAX and ensure the provided type is less than it. For mqd_size, add new function mqd_size_from_queue_type and confirm that the provided mqd_size matches expectations. Reviewed-by: David Yat Sin <david.yatsin@amd.com> Signed-off-by: David Francis <David.Francis@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
9d01579f3f
commit
f19d8086f6
|
|
@ -3777,6 +3777,12 @@ bool kfd_dqm_is_queue_in_process(struct device_queue_manager *dqm,
|
|||
dqm_unlock(dqm);
|
||||
return r;
|
||||
}
|
||||
|
||||
size_t mqd_size_from_queue_type(struct device_queue_manager *dqm, enum kfd_queue_type type)
|
||||
{
|
||||
return dqm->mqd_mgrs[get_mqd_type_from_queue_type(type)]->mqd_size;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
static void seq_reg_dump(struct seq_file *m,
|
||||
|
|
|
|||
|
|
@ -335,6 +335,8 @@ bool kfd_dqm_is_queue_in_process(struct device_queue_manager *dqm,
|
|||
int doorbell_off, u32 *queue_format);
|
||||
int kfd_reset_queue_mes(struct device_queue_manager *dqm, int queue_type,
|
||||
int pipe, int queue, unsigned int db);
|
||||
size_t mqd_size_from_queue_type(struct device_queue_manager *dqm,
|
||||
enum kfd_queue_type type);
|
||||
|
||||
static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -441,7 +441,8 @@ enum kfd_queue_type {
|
|||
KFD_QUEUE_TYPE_SDMA,
|
||||
KFD_QUEUE_TYPE_HIQ,
|
||||
KFD_QUEUE_TYPE_SDMA_XGMI,
|
||||
KFD_QUEUE_TYPE_SDMA_BY_ENG_ID
|
||||
KFD_QUEUE_TYPE_SDMA_BY_ENG_ID,
|
||||
KFD_QUEUE_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum kfd_queue_format {
|
||||
|
|
|
|||
|
|
@ -1003,6 +1003,23 @@ int kfd_criu_restore_queue(struct kfd_process *p,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
pdd = kfd_process_device_data_by_id(p, q_data->gpu_id);
|
||||
if (!pdd) {
|
||||
pr_err("Failed to get pdd\n");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (q_data->type >= KFD_QUEUE_TYPE_MAX) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (q_data->mqd_size != mqd_size_from_queue_type(pdd->dev->dqm, q_data->type)) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*priv_data_offset += sizeof(*q_data);
|
||||
q_extra_data_size = (uint64_t)q_data->ctl_stack_size + q_data->mqd_size;
|
||||
|
||||
|
|
@ -1025,13 +1042,6 @@ int kfd_criu_restore_queue(struct kfd_process *p,
|
|||
|
||||
*priv_data_offset += q_extra_data_size;
|
||||
|
||||
pdd = kfd_process_device_data_by_id(p, q_data->gpu_id);
|
||||
if (!pdd) {
|
||||
pr_err("Failed to get pdd\n");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* data stored in this order:
|
||||
* mqd[xcc0], mqd[xcc1],..., ctl_stack[xcc0], ctl_stack[xcc1]...
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user