diff options
author | Alex Deucher | 2013-04-25 08:29:17 -0500 |
---|---|---|
committer | Greg Kroah-Hartman | 2013-05-11 15:54:08 -0500 |
commit | d2444704cc6b3135247ee3533e6e04c562141afd (patch) | |
tree | 3712f2ac9f9582a43da4c72302db01d2c2749099 | |
parent | 67d3fdc21b2875d89eb32ec64265d17b9292ff47 (diff) | |
download | kernel-omap-d2444704cc6b3135247ee3533e6e04c562141afd.tar.gz kernel-omap-d2444704cc6b3135247ee3533e6e04c562141afd.tar.xz kernel-omap-d2444704cc6b3135247ee3533e6e04c562141afd.zip |
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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 f22eb5713528..8a9b27cb3712 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 = |