drm/amd/powerplay: fix null pointer dereference around dpm state relates
authorEvan Quan <evan.quan@amd.com>
Thu, 25 Jul 2019 04:10:34 +0000 (12:10 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 31 Jul 2019 05:06:58 +0000 (00:06 -0500)
DPM state relates are not supported on the new SW SMU ASICs. But still
it's not OK to trigger null pointer dereference on accessing them.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c

index 03ca8c69114fc22ebec9c25601c420a5d9d6bf2c..8c90baca07b2a0c3f724fe05b45350afff8eccbf 100644 (file)
@@ -159,12 +159,16 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev,
        struct amdgpu_device *adev = ddev->dev_private;
        enum amd_pm_state_type pm;
 
-       if (is_support_sw_smu(adev) && adev->smu.ppt_funcs->get_current_power_state)
-               pm = amdgpu_smu_get_current_power_state(adev);
-       else if (adev->powerplay.pp_funcs->get_current_power_state)
+       if (is_support_sw_smu(adev)) {
+               if (adev->smu.ppt_funcs->get_current_power_state)
+                       pm = amdgpu_smu_get_current_power_state(adev);
+               else
+                       pm = adev->pm.dpm.user_state;
+       } else if (adev->powerplay.pp_funcs->get_current_power_state) {
                pm = amdgpu_dpm_get_current_power_state(adev);
-       else
+       } else {
                pm = adev->pm.dpm.user_state;
+       }
 
        return snprintf(buf, PAGE_SIZE, "%s\n",
                        (pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
@@ -191,7 +195,11 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev,
                goto fail;
        }
 
-       if (adev->powerplay.pp_funcs->dispatch_tasks) {
+       if (is_support_sw_smu(adev)) {
+               mutex_lock(&adev->pm.mutex);
+               adev->pm.dpm.user_state = state;
+               mutex_unlock(&adev->pm.mutex);
+       } else if (adev->powerplay.pp_funcs->dispatch_tasks) {
                amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_ENABLE_USER_STATE, &state);
        } else {
                mutex_lock(&adev->pm.mutex);
index c097113c39769b3240bcb0c9f81943efd0334a2e..88ed85e3d233d9c4437ab3bacdf8b4224a08145d 100644 (file)
@@ -306,7 +306,8 @@ int smu_get_power_num_states(struct smu_context *smu,
 
        /* not support power state */
        memset(state_info, 0, sizeof(struct pp_states_info));
-       state_info->nums = 0;
+       state_info->nums = 1;
+       state_info->states[0] = POWER_STATE_TYPE_DEFAULT;
 
        return 0;
 }