| From: Alex Deucher <alexander.deucher@amd.com> |
| Date: Thu, 25 Apr 2013 09:29:17 -0400 |
| Subject: drm/radeon: fix possible segfault when parsing pm tables |
| |
| commit f8e6bfc2ce162855fa4f9822a45659f4b542c960 upstream. |
| |
| If we have a empty power table, bail early and allocate |
| the default power state. |
| |
| Should fix: |
| https://bugs.freedesktop.org/show_bug.cgi?id=63865 |
| |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/gpu/drm/radeon/radeon_atombios.c | 10 +++++++++- |
| 1 file changed, 9 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/gpu/drm/radeon/radeon_atombios.c |
| +++ b/drivers/gpu/drm/radeon/radeon_atombios.c |
| @@ -1989,6 +1989,8 @@ static int radeon_atombios_parse_power_t |
| num_modes = power_info->info.ucNumOfPowerModeEntries; |
| if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) |
| num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; |
| + if (num_modes == 0) |
| + return state_index; |
| rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); |
| if (!rdev->pm.power_state) |
| return state_index; |
| @@ -2361,6 +2363,8 @@ static int radeon_atombios_parse_power_t |
| power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
| |
| radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); |
| + if (power_info->pplib.ucNumStates == 0) |
| + return state_index; |
| rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * |
| power_info->pplib.ucNumStates, GFP_KERNEL); |
| if (!rdev->pm.power_state) |
| @@ -2459,6 +2463,8 @@ static int radeon_atombios_parse_power_t |
| non_clock_info_array = (struct NonClockInfoArray *) |
| (mode_info->atom_context->bios + data_offset + |
| le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); |
| + if (state_array->ucNumEntries == 0) |
| + return state_index; |
| rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * |
| state_array->ucNumEntries, GFP_KERNEL); |
| if (!rdev->pm.power_state) |
| @@ -2549,7 +2555,9 @@ void radeon_atombios_get_power_modes(str |
| default: |
| break; |
| } |
| - } else { |
| + } |
| + |
| + if (state_index == 0) { |
| rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); |
| if (rdev->pm.power_state) { |
| rdev->pm.power_state[0].clock_info = |