diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-07-01 15:32:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-02 15:11:12 -0400 |
commit | 7c5371c403abb29f01bc6cff6c5096abdf2dc524 (patch) | |
tree | 8c087cac6358dfefa14e6819c4b4dbb4c7326af4 /arch/x86/kernel/e820.c | |
parent | 43644679a1e80f53e6e0155ab75b1093ba3c0365 (diff) |
x86: add boundary check for 32bit res before expand e820 resource to alignment
fix hang with HIGHMEM_64G and 32bit resource. According to hpa and
Linus, use (resource_size_t)-1 to fend off big ranges.
Analyzed by hpa
Reported-and-tested-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/kernel/e820.c')
-rw-r--r-- | arch/x86/kernel/e820.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 7271fa33d791..c4ca89d9aaf4 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -1383,6 +1383,8 @@ static unsigned long ram_alignment(resource_size_t pos) | |||
1383 | return 32*1024*1024; | 1383 | return 32*1024*1024; |
1384 | } | 1384 | } |
1385 | 1385 | ||
1386 | #define MAX_RESOURCE_SIZE ((resource_size_t)-1) | ||
1387 | |||
1386 | void __init e820_reserve_resources_late(void) | 1388 | void __init e820_reserve_resources_late(void) |
1387 | { | 1389 | { |
1388 | int i; | 1390 | int i; |
@@ -1400,17 +1402,19 @@ void __init e820_reserve_resources_late(void) | |||
1400 | * avoid stolen RAM: | 1402 | * avoid stolen RAM: |
1401 | */ | 1403 | */ |
1402 | for (i = 0; i < e820.nr_map; i++) { | 1404 | for (i = 0; i < e820.nr_map; i++) { |
1403 | struct e820entry *entry = &e820_saved.map[i]; | 1405 | struct e820entry *entry = &e820.map[i]; |
1404 | resource_size_t start, end; | 1406 | u64 start, end; |
1405 | 1407 | ||
1406 | if (entry->type != E820_RAM) | 1408 | if (entry->type != E820_RAM) |
1407 | continue; | 1409 | continue; |
1408 | start = entry->addr + entry->size; | 1410 | start = entry->addr + entry->size; |
1409 | end = round_up(start, ram_alignment(start)); | 1411 | end = round_up(start, ram_alignment(start)) - 1; |
1410 | if (start == end) | 1412 | if (end > MAX_RESOURCE_SIZE) |
1413 | end = MAX_RESOURCE_SIZE; | ||
1414 | if (start >= end) | ||
1411 | continue; | 1415 | continue; |
1412 | reserve_region_with_split(&iomem_resource, start, | 1416 | reserve_region_with_split(&iomem_resource, start, end, |
1413 | end - 1, "RAM buffer"); | 1417 | "RAM buffer"); |
1414 | } | 1418 | } |
1415 | } | 1419 | } |
1416 | 1420 | ||