aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher2013-05-01 13:34:54 -0500
committerGreg Kroah-Hartman2013-05-11 15:54:09 -0500
commitd7a0a30e6fcba4c014fedfdb56e19837f8030ea9 (patch)
tree16c1009f0819242bf8682354362829b1c2b3b30b
parent9c9a03e19d6414c7c6f482d8130c7592cbd0ef6a (diff)
downloadkernel-omap-d7a0a30e6fcba4c014fedfdb56e19837f8030ea9.tar.gz
kernel-omap-d7a0a30e6fcba4c014fedfdb56e19837f8030ea9.tar.xz
kernel-omap-d7a0a30e6fcba4c014fedfdb56e19837f8030ea9.zip
drm/radeon: fix handling of v6 power tables
commit 441e76ca83ac604eaf0f046def96d8e3a27eea28 upstream. The code was mis-handling variable sized arrays. Reported-by: Sylvain BERTRAND <sylware@legeek.net> 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.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 8a9b27cb3712..96168ef4ab19 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2518,6 +2518,7 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2518 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); 2518 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2519 u16 data_offset; 2519 u16 data_offset;
2520 u8 frev, crev; 2520 u8 frev, crev;
2521 u8 *power_state_offset;
2521 2522
2522 if (!atom_parse_data_header(mode_info->atom_context, index, NULL, 2523 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2523 &frev, &crev, &data_offset)) 2524 &frev, &crev, &data_offset))
@@ -2540,11 +2541,11 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2540 state_array->ucNumEntries, GFP_KERNEL); 2541 state_array->ucNumEntries, GFP_KERNEL);
2541 if (!rdev->pm.power_state) 2542 if (!rdev->pm.power_state)
2542 return state_index; 2543 return state_index;
2544 power_state_offset = (u8 *)state_array->states;
2543 for (i = 0; i < state_array->ucNumEntries; i++) { 2545 for (i = 0; i < state_array->ucNumEntries; i++) {
2544 mode_index = 0; 2546 mode_index = 0;
2545 power_state = (union pplib_power_state *)&state_array->states[i]; 2547 power_state = (union pplib_power_state *)power_state_offset;
2546 /* XXX this might be an inagua bug... */ 2548 non_clock_array_index = power_state->v2.nonClockInfoIndex;
2547 non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
2548 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) 2549 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2549 &non_clock_info_array->nonClockInfo[non_clock_array_index]; 2550 &non_clock_info_array->nonClockInfo[non_clock_array_index];
2550 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * 2551 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
@@ -2556,9 +2557,6 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2556 if (power_state->v2.ucNumDPMLevels) { 2557 if (power_state->v2.ucNumDPMLevels) {
2557 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { 2558 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
2558 clock_array_index = power_state->v2.clockInfoIndex[j]; 2559 clock_array_index = power_state->v2.clockInfoIndex[j];
2559 /* XXX this might be an inagua bug... */
2560 if (clock_array_index >= clock_info_array->ucNumEntries)
2561 continue;
2562 clock_info = (union pplib_clock_info *) 2560 clock_info = (union pplib_clock_info *)
2563 &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; 2561 &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
2564 valid = radeon_atombios_parse_pplib_clock_info(rdev, 2562 valid = radeon_atombios_parse_pplib_clock_info(rdev,
@@ -2580,6 +2578,7 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2580 non_clock_info); 2578 non_clock_info);
2581 state_index++; 2579 state_index++;
2582 } 2580 }
2581 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
2583 } 2582 }
2584 /* if multiple clock modes, mark the lowest as no display */ 2583 /* if multiple clock modes, mark the lowest as no display */
2585 for (i = 0; i < state_index; i++) { 2584 for (i = 0; i < state_index; i++) {