diff --git a/sys/dev/drm/amd/amdgpu/si_dpm.c b/sys/dev/drm/amd/amdgpu/si_dpm.c --- a/sys/dev/drm/amd/amdgpu/si_dpm.c +++ b/sys/dev/drm/amd/amdgpu/si_dpm.c @@ -5659,7 +5659,8 @@ u32 threshold; u32 sclk_in_sr = 1350; /* ??? */ - if (state->performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS) + if (state->performance_level_count == 0 || + state->performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS) return -EINVAL; threshold = state->performance_levels[state->performance_level_count-1].sclk * 100 / 100; @@ -5735,10 +5736,15 @@ int ret; u32 address = si_pi->state_table_start + offsetof(SISLANDS_SMC_STATETABLE, driverState); - u32 state_size = sizeof(SISLANDS_SMC_SWSTATE) + + u32 state_size; + SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.driverState; + + if (new_state->performance_level_count == 0) + return -EINVAL; + + state_size = sizeof(SISLANDS_SMC_SWSTATE) + ((new_state->performance_level_count - 1) * sizeof(SISLANDS_SMC_HW_PERFORMANCE_LEVEL)); - SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.driverState; memset(smc_state, 0, state_size); @@ -7872,8 +7878,10 @@ if (low) return requested_state->performance_levels[0].sclk; - else + else if (requested_state->performance_level_count > 0) return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk; + else + return 0; } static u32 si_dpm_get_mclk(void *handle, bool low) @@ -7884,8 +7892,10 @@ if (low) return requested_state->performance_levels[0].mclk; - else + else if (requested_state->performance_level_count > 0) return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk; + else + return 0; } static void si_dpm_print_power_state(void *handle,