Skip to content

Commit 46806e5

Browse files
Roman Lialexdeucher
authored andcommitted
drm/amd/display: Fix array-index-out-of-bounds in dcn35_clkmgr
[Why] There is a potential memory access violation while iterating through array of dcn35 clks. [How] Limit iteration per array size. Cc: Mario Limonciello <[email protected]> Cc: Alex Deucher <[email protected]> Cc: [email protected] Reviewed-by: Nicholas Kazlauskas <[email protected]> Acked-by: Aurabindo Pillai <[email protected]> Signed-off-by: Roman Li <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent deb1102 commit 46806e5

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -655,10 +655,13 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk
655655
struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1];
656656
uint32_t max_fclk = 0, min_pstate = 0, max_dispclk = 0, max_dppclk = 0;
657657
uint32_t max_pstate = 0, max_dram_speed_mts = 0, min_dram_speed_mts = 0;
658+
uint32_t num_memps, num_fclk, num_dcfclk;
658659
int i;
659660

660661
/* Determine min/max p-state values. */
661-
for (i = 0; i < clock_table->NumMemPstatesEnabled; i++) {
662+
num_memps = (clock_table->NumMemPstatesEnabled > NUM_MEM_PSTATE_LEVELS) ? NUM_MEM_PSTATE_LEVELS :
663+
clock_table->NumMemPstatesEnabled;
664+
for (i = 0; i < num_memps; i++) {
662665
uint32_t dram_speed_mts = calc_dram_speed_mts(&clock_table->MemPstateTable[i]);
663666

664667
if (is_valid_clock_value(dram_speed_mts) && dram_speed_mts > max_dram_speed_mts) {
@@ -670,7 +673,7 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk
670673
min_dram_speed_mts = max_dram_speed_mts;
671674
min_pstate = max_pstate;
672675

673-
for (i = 0; i < clock_table->NumMemPstatesEnabled; i++) {
676+
for (i = 0; i < num_memps; i++) {
674677
uint32_t dram_speed_mts = calc_dram_speed_mts(&clock_table->MemPstateTable[i]);
675678

676679
if (is_valid_clock_value(dram_speed_mts) && dram_speed_mts < min_dram_speed_mts) {
@@ -699,9 +702,13 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk
699702
/* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */
700703
ASSERT(clock_table->NumDcfClkLevelsEnabled > 0);
701704

702-
max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, clock_table->NumFclkLevelsEnabled);
705+
num_fclk = (clock_table->NumFclkLevelsEnabled > NUM_FCLK_DPM_LEVELS) ? NUM_FCLK_DPM_LEVELS :
706+
clock_table->NumFclkLevelsEnabled;
707+
max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, num_fclk);
703708

704-
for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) {
709+
num_dcfclk = (clock_table->NumFclkLevelsEnabled > NUM_DCFCLK_DPM_LEVELS) ? NUM_DCFCLK_DPM_LEVELS :
710+
clock_table->NumDcfClkLevelsEnabled;
711+
for (i = 0; i < num_dcfclk; i++) {
705712
int j;
706713

707714
/* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */

0 commit comments

Comments
 (0)