The ci_enable_uvd_dpm() calls ci_send_msg_to_smc_with_parameter() but does not check the return value. This could lead to the execution with potentially invalid data. A proper implementation can be found in the ci_fan_ctrl_start_smc_fan_control().
Add a check after calling ci_send_msg_to_smc_with_parameter(), return -EINVAL if the sending fails.
Fixes: cc8dbbb4f62a ("drm/radeon: add dpm support for CI dGPUs (v2)") Cc: stable@vger.kernel.org # v3.12 Signed-off-by: Wentao Liang vulab@iscas.ac.cn --- drivers/gpu/drm/radeon/ci_dpm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index abe9d65cc460..3877863c6893 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -3889,6 +3889,7 @@ static int ci_enable_uvd_dpm(struct radeon_device *rdev, bool enable) struct ci_power_info *pi = ci_get_pi(rdev); const struct radeon_clock_and_voltage_limits *max_limits; int i; + PPSMC_Result result;
if (rdev->pm.dpm.ac_power) max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; @@ -3907,24 +3908,30 @@ static int ci_enable_uvd_dpm(struct radeon_device *rdev, bool enable) } }
- ci_send_msg_to_smc_with_parameter(rdev, + result = ci_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_UVDDPM_SetEnabledMask, pi->dpm_level_enable_mask.uvd_dpm_enable_mask); + if (result != PPSMC_Result_OK) + return -EINVAL;
if (pi->last_mclk_dpm_enable_mask & 0x1) { pi->uvd_enabled = true; pi->dpm_level_enable_mask.mclk_dpm_enable_mask &= 0xFFFFFFFE; - ci_send_msg_to_smc_with_parameter(rdev, + result = ci_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_MCLKDPM_SetEnabledMask, pi->dpm_level_enable_mask.mclk_dpm_enable_mask); + if (result != PPSMC_Result_OK) + return -EINVAL; } } else { if (pi->last_mclk_dpm_enable_mask & 0x1) { pi->uvd_enabled = false; pi->dpm_level_enable_mask.mclk_dpm_enable_mask |= 1; - ci_send_msg_to_smc_with_parameter(rdev, + result = ci_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_MCLKDPM_SetEnabledMask, pi->dpm_level_enable_mask.mclk_dpm_enable_mask); + if (result != PPSMC_Result_OK) + return -EINVAL; } }