mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
drm/amd/pm: Validate OD DPM triples before mutating tables
vega10_odn_edit_dpm_table() and smu7_odn_edit_dpm_table() could mutate the live ODN table for valid triples, then return 0 after detecting a truncated buffer or out-of-range index. Validate all (index, clock, voltage) triples first and return -EINVAL on any failure; only then apply updates. v2: Use distinct message for different error case, removed unused input_level from validation loop (Lijo) v3: Reject negative level indices, input[] is long but was compared only against unsigned table bounds, so negative values could pass and truncate when assigned to uint32_t input_level. Set DPMTABLE_OD_UPDATE_SCLK/MCLK only after validation passes, so a failed sysfs write does not leave need_update_dpm_table set for a later commit. Signed-off-by: Asad Kamal <asad.kamal@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
921926a12e
commit
b390cb9d77
|
|
@ -5648,23 +5648,29 @@ static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
|
|||
}
|
||||
|
||||
for (i = 0; i < size; i += 3) {
|
||||
if (i + 3 > size || input[i] >= podn_dpm_table_in_backend->num_of_pl) {
|
||||
pr_info("invalid clock voltage input \n");
|
||||
return 0;
|
||||
}
|
||||
input_level = input[i];
|
||||
input_clk = input[i+1] * 100;
|
||||
input_vol = input[i+2];
|
||||
|
||||
if (smu7_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol)) {
|
||||
podn_dpm_table_in_backend->entries[input_level].clock = input_clk;
|
||||
podn_vdd_dep_in_backend->entries[input_level].clk = input_clk;
|
||||
podn_dpm_table_in_backend->entries[input_level].vddc = input_vol;
|
||||
podn_vdd_dep_in_backend->entries[input_level].vddc = input_vol;
|
||||
podn_vdd_dep_in_backend->entries[input_level].vddgfx = input_vol;
|
||||
} else {
|
||||
if (i + 3 > size) {
|
||||
pr_info("truncated clock/voltage input\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (input[i] < 0 || input[i] >= podn_dpm_table_in_backend->num_of_pl) {
|
||||
pr_info("invalid clock/voltage level\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
input_clk = input[i + 1] * 100;
|
||||
input_vol = input[i + 2];
|
||||
if (!smu7_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i += 3) {
|
||||
input_level = input[i];
|
||||
input_clk = input[i + 1] * 100;
|
||||
input_vol = input[i + 2];
|
||||
podn_dpm_table_in_backend->entries[input_level].clock = input_clk;
|
||||
podn_vdd_dep_in_backend->entries[input_level].clk = input_clk;
|
||||
podn_dpm_table_in_backend->entries[input_level].vddc = input_vol;
|
||||
podn_vdd_dep_in_backend->entries[input_level].vddc = input_vol;
|
||||
podn_vdd_dep_in_backend->entries[input_level].vddgfx = input_vol;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -5454,11 +5454,9 @@ static int vega10_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
|
|||
if (PP_OD_EDIT_SCLK_VDDC_TABLE == type) {
|
||||
dpm_table = &data->dpm_table.gfx_table;
|
||||
podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_sclk;
|
||||
data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
|
||||
} else if (PP_OD_EDIT_MCLK_VDDC_TABLE == type) {
|
||||
dpm_table = &data->dpm_table.mem_table;
|
||||
podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_mclk;
|
||||
data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
|
||||
} else if (PP_OD_RESTORE_DEFAULT_TABLE == type) {
|
||||
memcpy(&(data->dpm_table), &(data->golden_dpm_table), sizeof(struct vega10_dpm_table));
|
||||
vega10_odn_initial_default_setting(hwmgr);
|
||||
|
|
@ -5476,21 +5474,32 @@ static int vega10_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
|
|||
}
|
||||
|
||||
for (i = 0; i < size; i += 3) {
|
||||
if (i + 3 > size || input[i] >= podn_vdd_dep_table->count) {
|
||||
pr_info("invalid clock voltage input\n");
|
||||
return 0;
|
||||
}
|
||||
input_level = input[i];
|
||||
input_clk = input[i+1] * 100;
|
||||
input_vol = input[i+2];
|
||||
|
||||
if (vega10_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol)) {
|
||||
dpm_table->dpm_levels[input_level].value = input_clk;
|
||||
podn_vdd_dep_table->entries[input_level].clk = input_clk;
|
||||
podn_vdd_dep_table->entries[input_level].vddc = input_vol;
|
||||
} else {
|
||||
if (i + 3 > size) {
|
||||
pr_info("truncated clock/voltage input\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (input[i] < 0 || input[i] >= podn_vdd_dep_table->count) {
|
||||
pr_info("invalid clock/voltage level\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
input_clk = input[i + 1] * 100;
|
||||
input_vol = input[i + 2];
|
||||
if (!vega10_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type == PP_OD_EDIT_SCLK_VDDC_TABLE)
|
||||
data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
|
||||
else
|
||||
data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
|
||||
|
||||
for (i = 0; i < size; i += 3) {
|
||||
input_level = input[i];
|
||||
input_clk = input[i + 1] * 100;
|
||||
input_vol = input[i + 2];
|
||||
dpm_table->dpm_levels[input_level].value = input_clk;
|
||||
podn_vdd_dep_table->entries[input_level].clk = input_clk;
|
||||
podn_vdd_dep_table->entries[input_level].vddc = input_vol;
|
||||
}
|
||||
vega10_odn_update_soc_table(hwmgr, type);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user