diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-04-25 09:29:17 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-05-02 10:01:46 -0400 |
commit | f8e6bfc2ce162855fa4f9822a45659f4b542c960 (patch) | |
tree | e2d9a8b10eb8d16e0da644c9b8ea9645fbbaf4b4 /drivers/gpu | |
parent | beb71fc61c2cad64e347f164991b8ef476529e64 (diff) |
drm/radeon: fix possible segfault when parsing pm tables
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>
Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 0dd87c0e0fac..c4b19f84e6e2 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -2028,6 +2028,8 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
2028 | num_modes = power_info->info.ucNumOfPowerModeEntries; | 2028 | num_modes = power_info->info.ucNumOfPowerModeEntries; |
2029 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | 2029 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) |
2030 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | 2030 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; |
2031 | if (num_modes == 0) | ||
2032 | return state_index; | ||
2031 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); | 2033 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); |
2032 | if (!rdev->pm.power_state) | 2034 | if (!rdev->pm.power_state) |
2033 | return state_index; | 2035 | return state_index; |
@@ -2432,6 +2434,8 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) | |||
2432 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | 2434 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
2433 | 2435 | ||
2434 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); | 2436 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); |
2437 | if (power_info->pplib.ucNumStates == 0) | ||
2438 | return state_index; | ||
2435 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * | 2439 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * |
2436 | power_info->pplib.ucNumStates, GFP_KERNEL); | 2440 | power_info->pplib.ucNumStates, GFP_KERNEL); |
2437 | if (!rdev->pm.power_state) | 2441 | if (!rdev->pm.power_state) |
@@ -2530,6 +2534,8 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) | |||
2530 | non_clock_info_array = (struct _NonClockInfoArray *) | 2534 | non_clock_info_array = (struct _NonClockInfoArray *) |
2531 | (mode_info->atom_context->bios + data_offset + | 2535 | (mode_info->atom_context->bios + data_offset + |
2532 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); | 2536 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); |
2537 | if (state_array->ucNumEntries == 0) | ||
2538 | return state_index; | ||
2533 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * | 2539 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * |
2534 | state_array->ucNumEntries, GFP_KERNEL); | 2540 | state_array->ucNumEntries, GFP_KERNEL); |
2535 | if (!rdev->pm.power_state) | 2541 | if (!rdev->pm.power_state) |
@@ -2620,7 +2626,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
2620 | default: | 2626 | default: |
2621 | break; | 2627 | break; |
2622 | } | 2628 | } |
2623 | } else { | 2629 | } |
2630 | |||
2631 | if (state_index == 0) { | ||
2624 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); | 2632 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); |
2625 | if (rdev->pm.power_state) { | 2633 | if (rdev->pm.power_state) { |
2626 | rdev->pm.power_state[0].clock_info = | 2634 | rdev->pm.power_state[0].clock_info = |