Commit c8c19ebf authored by Jesse Zhang's avatar Jesse Zhang Committed by Alex Deucher

drm/amd/pm: Fix negative array index read

Avoid using the negative values
for clk_idex as an index into an array pptable->DpmDescriptor.

V2: fix clk_index return check (Tim Huang)
Signed-off-by: default avatarJesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: default avatarTim Huang <Tim.Huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f45ed399
...@@ -1219,19 +1219,22 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu, ...@@ -1219,19 +1219,22 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu,
value); value);
} }
static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type) static int navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type)
{ {
PPTable_t *pptable = smu->smu_table.driver_pptable; PPTable_t *pptable = smu->smu_table.driver_pptable;
DpmDescriptor_t *dpm_desc = NULL; DpmDescriptor_t *dpm_desc = NULL;
uint32_t clk_index = 0; int clk_index = 0;
clk_index = smu_cmn_to_asic_specific_index(smu, clk_index = smu_cmn_to_asic_specific_index(smu,
CMN2ASIC_MAPPING_CLK, CMN2ASIC_MAPPING_CLK,
clk_type); clk_type);
if (clk_index < 0)
return clk_index;
dpm_desc = &pptable->DpmDescriptor[clk_index]; dpm_desc = &pptable->DpmDescriptor[clk_index];
/* 0 - Fine grained DPM, 1 - Discrete DPM */ /* 0 - Fine grained DPM, 1 - Discrete DPM */
return dpm_desc->SnapToDiscrete == 0; return dpm_desc->SnapToDiscrete == 0 ? 1 : 0;
} }
static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap) static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap)
...@@ -1287,7 +1290,11 @@ static int navi10_emit_clk_levels(struct smu_context *smu, ...@@ -1287,7 +1290,11 @@ static int navi10_emit_clk_levels(struct smu_context *smu,
if (ret) if (ret)
return ret; return ret;
if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
if (ret < 0)
return ret;
if (!ret) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ret = smu_v11_0_get_dpm_freq_by_index(smu, ret = smu_v11_0_get_dpm_freq_by_index(smu,
clk_type, i, &value); clk_type, i, &value);
...@@ -1496,7 +1503,11 @@ static int navi10_print_clk_levels(struct smu_context *smu, ...@@ -1496,7 +1503,11 @@ static int navi10_print_clk_levels(struct smu_context *smu,
if (ret) if (ret)
return size; return size;
if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
if (ret < 0)
return ret;
if (!ret) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value); ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
if (ret) if (ret)
...@@ -1665,7 +1676,11 @@ static int navi10_force_clk_levels(struct smu_context *smu, ...@@ -1665,7 +1676,11 @@ static int navi10_force_clk_levels(struct smu_context *smu,
case SMU_UCLK: case SMU_UCLK:
case SMU_FCLK: case SMU_FCLK:
/* There is only 2 levels for fine grained DPM */ /* There is only 2 levels for fine grained DPM */
if (navi10_is_support_fine_grained_dpm(smu, clk_type)) { ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
if (ret < 0)
return ret;
if (ret) {
soft_max_level = (soft_max_level >= 1 ? 1 : 0); soft_max_level = (soft_max_level >= 1 ? 1 : 0);
soft_min_level = (soft_min_level >= 1 ? 1 : 0); soft_min_level = (soft_min_level >= 1 ? 1 : 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment