drm/amd/pm: fix double free in si_parse_power_table()
authorjsg <jsg@openbsd.org>
Fri, 10 Jun 2022 00:57:24 +0000 (00:57 +0000)
committerjsg <jsg@openbsd.org>
Fri, 10 Jun 2022 00:57:24 +0000 (00:57 +0000)
From Keita Suzuki
a5ce7051db044290b1a95045ff03c249005a3aa4 in linux 5.15.y/5.15.46
f3fa2becf2fc25b6ac7cf8d8b1a2e4a86b3b72bd in mainline linux

sys/dev/pci/drm/amd/pm/powerplay/amdgpu_si_dpm.c

index 81f82aa..66fc63f 100644 (file)
@@ -7247,17 +7247,15 @@ static int si_parse_power_table(struct amdgpu_device *adev)
        if (!adev->pm.dpm.ps)
                return -ENOMEM;
        power_state_offset = (u8 *)state_array->states;
-       for (i = 0; i < state_array->ucNumEntries; i++) {
+       for (adev->pm.dpm.num_ps = 0, i = 0; i < state_array->ucNumEntries; i++) {
                u8 *idx;
                power_state = (union pplib_power_state *)power_state_offset;
                non_clock_array_index = power_state->v2.nonClockInfoIndex;
                non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
                        &non_clock_info_array->nonClockInfo[non_clock_array_index];
                ps = kzalloc(sizeof(struct  si_ps), GFP_KERNEL);
-               if (ps == NULL) {
-                       kfree(adev->pm.dpm.ps);
+               if (ps == NULL)
                        return -ENOMEM;
-               }
                adev->pm.dpm.ps[i].ps_priv = ps;
                si_parse_pplib_non_clock_info(adev, &adev->pm.dpm.ps[i],
                                              non_clock_info,
@@ -7279,8 +7277,8 @@ static int si_parse_power_table(struct amdgpu_device *adev)
                        k++;
                }
                power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
+               adev->pm.dpm.num_ps++;
        }
-       adev->pm.dpm.num_ps = state_array->ucNumEntries;
 
        /* fill in the vce power states */
        for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {