--- a/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c +++ b/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c @@ -672,7 +672,8 @@ void *smu_atom_get_data_table(void *dev, } int smu_get_voltage_dependency_table_ppt_v1( - const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table, - struct phm_ppt_v1_clock_voltage_dependency_table *dep_table) + const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table, + struct phm_ppt_v1_clock_voltage_dependency_table *dep_table, + uint32_t max_entries) { - uint8_t i = 0; + uint32_t i; PP_ASSERT_WITH_CODE((0 != allowed_dep_table->count), "Voltage Lookup Table empty", return -EINVAL); - dep_table->count = allowed_dep_table->count; + /* The destination tables of all callers are fixed-size embedded + * arrays (entries[MAX_REGULAR_DPM_NUMBER]); never copy more than + * the destination can hold. Also fixes the uint8_t loop counter + * wrap (infinite loop) when count > 255 (DF-1799). */ + dep_table->count = (allowed_dep_table->count > max_entries) + ? max_entries : allowed_dep_table->count; for (i=0; icount; i++) { dep_table->entries[i].clk = allowed_dep_table->entries[i].clk; dep_table->entries[i].vddInd = allowed_dep_table->entries[i].vddInd; --- a/sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -841,12 +841,12 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr) - smu_get_voltage_dependency_table_ppt_v1(dep_sclk_table, - (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk)); + smu_get_voltage_dependency_table_ppt_v1(dep_sclk_table, + (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk), + MAX_REGULAR_DPM_NUMBER); @@ -855,8 +855,8 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr) - smu_get_voltage_dependency_table_ppt_v1(dep_mclk_table, - (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk)); + smu_get_voltage_dependency_table_ppt_v1(dep_mclk_table, + (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk), + MAX_REGULAR_DPM_NUMBER); --- a/sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -320,8 +320,9 @@ static int vega10_odn_initial_default_setting(struct pp_hwmgr *hwmgr) for (i = 0; i < 3; i++) - smu_get_voltage_dependency_table_ppt_v1(dep_table[i], od_table[i]); + smu_get_voltage_dependency_table_ppt_v1(dep_table[i], od_table[i], + MAX_REGULAR_DPM_NUMBER); - if (odn_table->max_vddc == 0 || odn_table->max_vddc > 2000) + if (odn_table->max_vddc == 0 || odn_table->max_vddc > 2000) --- a/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.h +++ b/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.h @@ -114,7 +114,8 @@ -int smu_get_voltage_dependency_table_ppt_v1( - const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table, - struct phm_ppt_v1_clock_voltage_dependency_table *dep_table); +int smu_get_voltage_dependency_table_ppt_v1( + const struct phm_ppt_v1_clock_voltage_dependency_table *allowed_dep_table, + struct phm_ppt_v1_clock_voltage_dependency_table *dep_table, + uint32_t max_entries);