Commit c0640304 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher

drm/amd/powerplay: input check for unsupported message/clock index

This can avoid them to be handled in a wrong way without notice.
Since not all SMU messages/clocks are supported on every SMU11 ASIC.
Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-by: default avatarFeifei Xu <Feifei.Xu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7e01a2ec
...@@ -331,7 +331,7 @@ int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, int ...@@ -331,7 +331,7 @@ int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, int
int ret = 0; int ret = 0;
int table_id = smu_table_get_index(smu, table_index); int table_id = smu_table_get_index(smu, table_index);
if (!table_data || table_id >= smu_table->table_count) if (!table_data || table_id >= smu_table->table_count || table_id < 0)
return -EINVAL; return -EINVAL;
table = &smu_table->tables[table_index]; table = &smu_table->tables[table_index];
...@@ -462,10 +462,12 @@ int smu_feature_init_dpm(struct smu_context *smu) ...@@ -462,10 +462,12 @@ int smu_feature_init_dpm(struct smu_context *smu)
int smu_feature_is_enabled(struct smu_context *smu, enum smu_feature_mask mask) int smu_feature_is_enabled(struct smu_context *smu, enum smu_feature_mask mask)
{ {
struct smu_feature *feature = &smu->smu_feature; struct smu_feature *feature = &smu->smu_feature;
uint32_t feature_id; int feature_id;
int ret = 0; int ret = 0;
feature_id = smu_feature_get_index(smu, mask); feature_id = smu_feature_get_index(smu, mask);
if (feature_id < 0)
return 0;
WARN_ON(feature_id > feature->feature_num); WARN_ON(feature_id > feature->feature_num);
...@@ -480,10 +482,12 @@ int smu_feature_set_enabled(struct smu_context *smu, enum smu_feature_mask mask, ...@@ -480,10 +482,12 @@ int smu_feature_set_enabled(struct smu_context *smu, enum smu_feature_mask mask,
bool enable) bool enable)
{ {
struct smu_feature *feature = &smu->smu_feature; struct smu_feature *feature = &smu->smu_feature;
uint32_t feature_id; int feature_id;
int ret = 0; int ret = 0;
feature_id = smu_feature_get_index(smu, mask); feature_id = smu_feature_get_index(smu, mask);
if (feature_id < 0)
return -EINVAL;
WARN_ON(feature_id > feature->feature_num); WARN_ON(feature_id > feature->feature_num);
...@@ -506,10 +510,12 @@ int smu_feature_set_enabled(struct smu_context *smu, enum smu_feature_mask mask, ...@@ -506,10 +510,12 @@ int smu_feature_set_enabled(struct smu_context *smu, enum smu_feature_mask mask,
int smu_feature_is_supported(struct smu_context *smu, enum smu_feature_mask mask) int smu_feature_is_supported(struct smu_context *smu, enum smu_feature_mask mask)
{ {
struct smu_feature *feature = &smu->smu_feature; struct smu_feature *feature = &smu->smu_feature;
uint32_t feature_id; int feature_id;
int ret = 0; int ret = 0;
feature_id = smu_feature_get_index(smu, mask); feature_id = smu_feature_get_index(smu, mask);
if (feature_id < 0)
return 0;
WARN_ON(feature_id > feature->feature_num); WARN_ON(feature_id > feature->feature_num);
...@@ -525,10 +531,12 @@ int smu_feature_set_supported(struct smu_context *smu, ...@@ -525,10 +531,12 @@ int smu_feature_set_supported(struct smu_context *smu,
bool enable) bool enable)
{ {
struct smu_feature *feature = &smu->smu_feature; struct smu_feature *feature = &smu->smu_feature;
uint32_t feature_id; int feature_id;
int ret = 0; int ret = 0;
feature_id = smu_feature_get_index(smu, mask); feature_id = smu_feature_get_index(smu, mask);
if (feature_id < 0)
return -EINVAL;
WARN_ON(feature_id > feature->feature_num); WARN_ON(feature_id > feature->feature_num);
......
...@@ -216,8 +216,10 @@ static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index) ...@@ -216,8 +216,10 @@ static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = navi10_message_map[index]; mapping = navi10_message_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU message: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -230,8 +232,10 @@ static int navi10_get_smu_clk_index(struct smu_context *smc, uint32_t index) ...@@ -230,8 +232,10 @@ static int navi10_get_smu_clk_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = navi10_clk_map[index]; mapping = navi10_clk_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU clock: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -244,8 +248,10 @@ static int navi10_get_smu_feature_index(struct smu_context *smc, uint32_t index) ...@@ -244,8 +248,10 @@ static int navi10_get_smu_feature_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = navi10_feature_mask_map[index]; mapping = navi10_feature_mask_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU feature: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -258,8 +264,10 @@ static int navi10_get_smu_table_index(struct smu_context *smc, uint32_t index) ...@@ -258,8 +264,10 @@ static int navi10_get_smu_table_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = navi10_table_map[index]; mapping = navi10_table_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU table: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -272,8 +280,10 @@ static int navi10_get_pwr_src_index(struct smu_context *smc, uint32_t index) ...@@ -272,8 +280,10 @@ static int navi10_get_pwr_src_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = navi10_pwr_src_map[index]; mapping = navi10_pwr_src_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported power source: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -287,8 +297,10 @@ static int navi10_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_P ...@@ -287,8 +297,10 @@ static int navi10_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_P
return -EINVAL; return -EINVAL;
mapping = navi10_workload_map[profile]; mapping = navi10_workload_map[profile];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported workload: %d\n", (int)profile);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -969,7 +981,7 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) ...@@ -969,7 +981,7 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf)
{ {
DpmActivityMonitorCoeffInt_t activity_monitor; DpmActivityMonitorCoeffInt_t activity_monitor;
uint32_t i, size = 0; uint32_t i, size = 0;
uint16_t workload_type = 0; int16_t workload_type = 0;
static const char *profile_name[] = { static const char *profile_name[] = {
"BOOTUP_DEFAULT", "BOOTUP_DEFAULT",
"3D_FULL_SCREEN", "3D_FULL_SCREEN",
...@@ -1002,6 +1014,9 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) ...@@ -1002,6 +1014,9 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf)
for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
workload_type = smu_workload_get_type(smu, i); workload_type = smu_workload_get_type(smu, i);
if (workload_type < 0)
return -EINVAL;
result = smu_update_table(smu, result = smu_update_table(smu,
SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type, SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
(void *)(&activity_monitor), false); (void *)(&activity_monitor), false);
...@@ -1130,6 +1145,8 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u ...@@ -1130,6 +1145,8 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u
/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
workload_type = smu_workload_get_type(smu, smu->power_profile_mode); workload_type = smu_workload_get_type(smu, smu->power_profile_mode);
if (workload_type < 0)
return -EINVAL;
smu_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, smu_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1 << workload_type); 1 << workload_type);
......
...@@ -937,11 +937,17 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock, ...@@ -937,11 +937,17 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
enum smu_clk_type clock_select) enum smu_clk_type clock_select)
{ {
int ret = 0; int ret = 0;
int clk_id;
if (!smu->pm_enabled) if (!smu->pm_enabled)
return ret; return ret;
clk_id = smu_clk_get_index(smu, clock_select);
if (clk_id < 0)
return -EINVAL;
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq, ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq,
smu_clk_get_index(smu, clock_select) << 16); clk_id << 16);
if (ret) { if (ret) {
pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!"); pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!");
return ret; return ret;
...@@ -956,7 +962,7 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock, ...@@ -956,7 +962,7 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
/* if DC limit is zero, return AC limit */ /* if DC limit is zero, return AC limit */
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
smu_clk_get_index(smu, clock_select) << 16); clk_id << 16);
if (ret) { if (ret) {
pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!"); pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!");
return ret; return ret;
...@@ -1052,6 +1058,11 @@ static int smu_v11_0_get_power_limit(struct smu_context *smu, ...@@ -1052,6 +1058,11 @@ static int smu_v11_0_get_power_limit(struct smu_context *smu,
bool get_default) bool get_default)
{ {
int ret = 0; int ret = 0;
int power_src;
power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC);
if (power_src < 0)
return -EINVAL;
if (get_default) { if (get_default) {
mutex_lock(&smu->mutex); mutex_lock(&smu->mutex);
...@@ -1063,7 +1074,7 @@ static int smu_v11_0_get_power_limit(struct smu_context *smu, ...@@ -1063,7 +1074,7 @@ static int smu_v11_0_get_power_limit(struct smu_context *smu,
mutex_unlock(&smu->mutex); mutex_unlock(&smu->mutex);
} else { } else {
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetPptLimit, ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetPptLimit,
smu_power_get_index(smu, SMU_POWER_SOURCE_AC) << 16); power_src << 16);
if (ret) { if (ret) {
pr_err("[%s] get PPT limit failed!", __func__); pr_err("[%s] get PPT limit failed!", __func__);
return ret; return ret;
...@@ -1106,16 +1117,21 @@ static int smu_v11_0_get_current_clk_freq(struct smu_context *smu, ...@@ -1106,16 +1117,21 @@ static int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
{ {
int ret = 0; int ret = 0;
uint32_t freq = 0; uint32_t freq = 0;
int asic_clk_id;
if (clk_id >= SMU_CLK_COUNT || !value) if (clk_id >= SMU_CLK_COUNT || !value)
return -EINVAL; return -EINVAL;
asic_clk_id = smu_clk_get_index(smu, clk_id);
if (asic_clk_id < 0)
return -EINVAL;
/* if don't has GetDpmClockFreq Message, try get current clock by SmuMetrics_t */ /* if don't has GetDpmClockFreq Message, try get current clock by SmuMetrics_t */
if (smu_msg_get_index(smu, SMU_MSG_GetDpmClockFreq) == 0) if (smu_msg_get_index(smu, SMU_MSG_GetDpmClockFreq) < 0)
ret = smu_get_current_clk_freq_by_table(smu, clk_id, &freq); ret = smu_get_current_clk_freq_by_table(smu, clk_id, &freq);
else { else {
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDpmClockFreq, ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDpmClockFreq,
(smu_clk_get_index(smu, clk_id) << 16)); (asic_clk_id << 16));
if (ret) if (ret)
return ret; return ret;
...@@ -1295,6 +1311,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu, ...@@ -1295,6 +1311,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
int ret = 0; int ret = 0;
enum smu_clk_type clk_select = 0; enum smu_clk_type clk_select = 0;
uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000; uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
int clk_id;
if (!smu->pm_enabled) if (!smu->pm_enabled)
return -EINVAL; return -EINVAL;
...@@ -1326,9 +1343,15 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu, ...@@ -1326,9 +1343,15 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
if (ret) if (ret)
goto failed; goto failed;
clk_id = smu_clk_get_index(smu, clk_select);
if (clk_id < 0) {
ret = -EINVAL;
goto failed;
}
mutex_lock(&smu->mutex); mutex_lock(&smu->mutex);
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq, ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
(smu_clk_get_index(smu, clk_select) << 16) | clk_freq); (clk_id << 16) | clk_freq);
mutex_unlock(&smu->mutex); mutex_unlock(&smu->mutex);
} }
......
...@@ -231,8 +231,10 @@ static int vega20_get_smu_table_index(struct smu_context *smc, uint32_t index) ...@@ -231,8 +231,10 @@ static int vega20_get_smu_table_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = vega20_table_map[index]; mapping = vega20_table_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU table: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -245,8 +247,10 @@ static int vega20_get_pwr_src_index(struct smu_context *smc, uint32_t index) ...@@ -245,8 +247,10 @@ static int vega20_get_pwr_src_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = vega20_pwr_src_map[index]; mapping = vega20_pwr_src_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported power source: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -259,8 +263,10 @@ static int vega20_get_smu_feature_index(struct smu_context *smc, uint32_t index) ...@@ -259,8 +263,10 @@ static int vega20_get_smu_feature_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = vega20_feature_mask_map[index]; mapping = vega20_feature_mask_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU feature: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -273,8 +279,10 @@ static int vega20_get_smu_clk_index(struct smu_context *smc, uint32_t index) ...@@ -273,8 +279,10 @@ static int vega20_get_smu_clk_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = vega20_clk_map[index]; mapping = vega20_clk_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU clock: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -287,8 +295,10 @@ static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index) ...@@ -287,8 +295,10 @@ static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index)
return -EINVAL; return -EINVAL;
mapping = vega20_message_map[index]; mapping = vega20_message_map[index];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU message: %d\n", index);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -301,8 +311,10 @@ static int vega20_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_P ...@@ -301,8 +311,10 @@ static int vega20_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_P
return -EINVAL; return -EINVAL;
mapping = vega20_workload_map[profile]; mapping = vega20_workload_map[profile];
if (!(mapping.valid_mapping)) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU workload: %d\n", (int)profile);
return -EINVAL; return -EINVAL;
}
return mapping.map_to; return mapping.map_to;
} }
...@@ -1778,7 +1790,7 @@ static int vega20_get_power_profile_mode(struct smu_context *smu, char *buf) ...@@ -1778,7 +1790,7 @@ static int vega20_get_power_profile_mode(struct smu_context *smu, char *buf)
{ {
DpmActivityMonitorCoeffInt_t activity_monitor; DpmActivityMonitorCoeffInt_t activity_monitor;
uint32_t i, size = 0; uint32_t i, size = 0;
uint16_t workload_type = 0; int16_t workload_type = 0;
static const char *profile_name[] = { static const char *profile_name[] = {
"BOOTUP_DEFAULT", "BOOTUP_DEFAULT",
"3D_FULL_SCREEN", "3D_FULL_SCREEN",
...@@ -1811,6 +1823,9 @@ static int vega20_get_power_profile_mode(struct smu_context *smu, char *buf) ...@@ -1811,6 +1823,9 @@ static int vega20_get_power_profile_mode(struct smu_context *smu, char *buf)
for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
workload_type = smu_workload_get_type(smu, i); workload_type = smu_workload_get_type(smu, i);
if (workload_type < 0)
return -EINVAL;
result = smu_update_table(smu, result = smu_update_table(smu,
SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type, SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
(void *)(&activity_monitor), false); (void *)(&activity_monitor), false);
...@@ -1963,6 +1978,8 @@ static int vega20_set_power_profile_mode(struct smu_context *smu, long *input, u ...@@ -1963,6 +1978,8 @@ static int vega20_set_power_profile_mode(struct smu_context *smu, long *input, u
/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
workload_type = smu_workload_get_type(smu, smu->power_profile_mode); workload_type = smu_workload_get_type(smu, smu->power_profile_mode);
if (workload_type < 0)
return -EINVAL;
smu_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, smu_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1 << workload_type); 1 << workload_type);
......
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