diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2991-drm-amd-powerplay-input-check-for-unsupported-messag.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2991-drm-amd-powerplay-input-check-for-unsupported-messag.patch | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2991-drm-amd-powerplay-input-check-for-unsupported-messag.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2991-drm-amd-powerplay-input-check-for-unsupported-messag.patch new file mode 100644 index 00000000..fdad03f9 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2991-drm-amd-powerplay-input-check-for-unsupported-messag.patch @@ -0,0 +1,401 @@ +From 88f16f4dae5ced672fd9a3c2938b3233a6d24837 Mon Sep 17 00:00:00 2001 +From: Evan Quan <evan.quan@amd.com> +Date: Thu, 11 Jul 2019 14:36:44 +0800 +Subject: [PATCH 2991/4256] 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. + +Change-Id: I440b80833c81066cd36613beae555f2fa068199f +Signed-off-by: Evan Quan <evan.quan@amd.com> +Reviewed-by: Feifei Xu <Feifei.Xu@amd.com> +--- + drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 18 +++++++---- + drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 31 ++++++++++++++----- + drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 35 ++++++++++++++++++---- + drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 31 ++++++++++++++----- + 4 files changed, 90 insertions(+), 25 deletions(-) + +diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +index 342d57f2fc5f..40604fe1c684 100644 +--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +@@ -331,7 +331,7 @@ int smu_update_table(struct smu_context *smu, enum smu_table_id table_index, + int ret = 0; + 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; + + table = &smu_table->tables[table_index]; +@@ -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) + { + struct smu_feature *feature = &smu->smu_feature; +- uint32_t feature_id; ++ int feature_id; + int ret = 0; + + feature_id = smu_feature_get_index(smu, mask); ++ if (feature_id < 0) ++ return 0; + + 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, + bool enable) + { + struct smu_feature *feature = &smu->smu_feature; +- uint32_t feature_id; ++ int feature_id; + int ret = 0; + + feature_id = smu_feature_get_index(smu, mask); ++ if (feature_id < 0) ++ return -EINVAL; + + 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, + int smu_feature_is_supported(struct smu_context *smu, enum smu_feature_mask mask) + { + struct smu_feature *feature = &smu->smu_feature; +- uint32_t feature_id; ++ int feature_id; + int ret = 0; + + feature_id = smu_feature_get_index(smu, mask); ++ if (feature_id < 0) ++ return 0; + + WARN_ON(feature_id > feature->feature_num); + +@@ -525,10 +531,12 @@ int smu_feature_set_supported(struct smu_context *smu, + bool enable) + { + struct smu_feature *feature = &smu->smu_feature; +- uint32_t feature_id; ++ int feature_id; + int ret = 0; + + feature_id = smu_feature_get_index(smu, mask); ++ if (feature_id < 0) ++ return -EINVAL; + + WARN_ON(feature_id > feature->feature_num); + +diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +index 102310461119..0c40d390d04b 100644 +--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +@@ -216,8 +216,10 @@ static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + mapping = navi10_message_map[index]; +- if (!(mapping.valid_mapping)) ++ if (!(mapping.valid_mapping)) { ++ pr_warn("Unsupported SMU message: %d\n", index); + return -EINVAL; ++ } + + return mapping.map_to; + } +@@ -230,8 +232,10 @@ static int navi10_get_smu_clk_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + mapping = navi10_clk_map[index]; +- if (!(mapping.valid_mapping)) ++ if (!(mapping.valid_mapping)) { ++ pr_warn("Unsupported SMU clock: %d\n", index); + return -EINVAL; ++ } + + return mapping.map_to; + } +@@ -244,8 +248,10 @@ static int navi10_get_smu_feature_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + 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 mapping.map_to; + } +@@ -258,8 +264,10 @@ static int navi10_get_smu_table_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + mapping = navi10_table_map[index]; +- if (!(mapping.valid_mapping)) ++ if (!(mapping.valid_mapping)) { ++ pr_warn("Unsupported SMU table: %d\n", index); + return -EINVAL; ++ } + + return mapping.map_to; + } +@@ -272,8 +280,10 @@ static int navi10_get_pwr_src_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + 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 mapping.map_to; + } +@@ -287,8 +297,10 @@ static int navi10_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_P + return -EINVAL; + + mapping = navi10_workload_map[profile]; +- if (!(mapping.valid_mapping)) ++ if (!(mapping.valid_mapping)) { ++ pr_warn("Unsupported workload: %d\n", (int)profile); + return -EINVAL; ++ } + + return mapping.map_to; + } +@@ -969,7 +981,7 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) + { + DpmActivityMonitorCoeffInt_t activity_monitor; + uint32_t i, size = 0; +- uint16_t workload_type = 0; ++ int16_t workload_type = 0; + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", +@@ -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++) { + /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ + workload_type = smu_workload_get_type(smu, i); ++ if (workload_type < 0) ++ return -EINVAL; ++ + result = smu_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF | workload_type << 16, + (void *)(&activity_monitor), false); +@@ -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 */ + 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, + 1 << workload_type); + +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index 7d723a5e4135..e60a5ceb5bff 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -928,11 +928,17 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock, + enum smu_clk_type clock_select) + { + int ret = 0; ++ int clk_id; + + if (!smu->pm_enabled) + 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, +- smu_clk_get_index(smu, clock_select) << 16); ++ clk_id << 16); + if (ret) { + pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!"); + return ret; +@@ -947,7 +953,7 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock, + + /* if DC limit is zero, return AC limit */ + ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, +- smu_clk_get_index(smu, clock_select) << 16); ++ clk_id << 16); + if (ret) { + pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!"); + return ret; +@@ -1043,6 +1049,11 @@ static int smu_v11_0_get_power_limit(struct smu_context *smu, + bool get_default) + { + 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) { + mutex_lock(&smu->mutex); +@@ -1054,7 +1065,7 @@ static int smu_v11_0_get_power_limit(struct smu_context *smu, + mutex_unlock(&smu->mutex); + } else { + 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) { + pr_err("[%s] get PPT limit failed!", __func__); + return ret; +@@ -1097,16 +1108,21 @@ static int smu_v11_0_get_current_clk_freq(struct smu_context *smu, + { + int ret = 0; + uint32_t freq = 0; ++ int asic_clk_id; + + if (clk_id >= SMU_CLK_COUNT || !value) + 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 (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); + else { + 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) + return ret; + +@@ -1286,6 +1302,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu, + int ret = 0; + enum smu_clk_type clk_select = 0; + uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000; ++ int clk_id; + + if (!smu->pm_enabled) + return -EINVAL; +@@ -1317,9 +1334,15 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu, + if (ret) + goto failed; + ++ clk_id = smu_clk_get_index(smu, clk_select); ++ if (clk_id < 0) { ++ ret = -EINVAL; ++ goto failed; ++ } ++ + mutex_lock(&smu->mutex); + 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); + } + +diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +index 52ea26e328c3..6b0180d1552b 100644 +--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +@@ -231,8 +231,10 @@ static int vega20_get_smu_table_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + mapping = vega20_table_map[index]; +- if (!(mapping.valid_mapping)) ++ if (!(mapping.valid_mapping)) { ++ pr_warn("Unsupported SMU table: %d\n", index); + return -EINVAL; ++ } + + return mapping.map_to; + } +@@ -245,8 +247,10 @@ static int vega20_get_pwr_src_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + 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 mapping.map_to; + } +@@ -259,8 +263,10 @@ static int vega20_get_smu_feature_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + 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 mapping.map_to; + } +@@ -273,8 +279,10 @@ static int vega20_get_smu_clk_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + mapping = vega20_clk_map[index]; +- if (!(mapping.valid_mapping)) ++ if (!(mapping.valid_mapping)) { ++ pr_warn("Unsupported SMU clock: %d\n", index); + return -EINVAL; ++ } + + return mapping.map_to; + } +@@ -287,8 +295,10 @@ static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index) + return -EINVAL; + + mapping = vega20_message_map[index]; +- if (!(mapping.valid_mapping)) ++ if (!(mapping.valid_mapping)) { ++ pr_warn("Unsupported SMU message: %d\n", index); + return -EINVAL; ++ } + + return mapping.map_to; + } +@@ -301,8 +311,10 @@ static int vega20_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_P + return -EINVAL; + + 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 mapping.map_to; + } +@@ -1778,7 +1790,7 @@ static int vega20_get_power_profile_mode(struct smu_context *smu, char *buf) + { + DpmActivityMonitorCoeffInt_t activity_monitor; + uint32_t i, size = 0; +- uint16_t workload_type = 0; ++ int16_t workload_type = 0; + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", +@@ -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++) { + /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ + workload_type = smu_workload_get_type(smu, i); ++ if (workload_type < 0) ++ return -EINVAL; ++ + result = smu_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF | workload_type << 16, + (void *)(&activity_monitor), false); +@@ -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 */ + 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, + 1 << workload_type); + +-- +2.17.1 + |