diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-05-06 11:06:44 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-11 03:45:14 -0400 |
commit | 45fbe3ee01b8e463b28c2751b5dcc0cbdc142d90 (patch) | |
tree | e90eb280684631d342ab34fdea298eb9badcd7d7 /arch/x86/kernel/e820.c | |
parent | 134cbf35c739bf89c51fd975a33a6b87507482c4 (diff) |
x86, e820, pci: reserve extra free space near end of RAM
The point is to take all RAM resources we have, and
_after_ we've added all the resources we've seen in
the E820 tree, we then _also_ try to add fake reserved
entries for any "round up to X" at the end of the RAM
resources.
[ Impact: improve PCI mem-resource allocation robustness, protect "stolen RAM" ]
Reported-by: Yannick Roehlly <yannick.roehlly@free.fr>
Acked-by: Jesse Barnes <jesse.barnes@intel.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: yannick.roehlly@free.fr
LKML-Reference: <4A01A784.2050407@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/e820.c')
-rw-r--r-- | arch/x86/kernel/e820.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 006281302925..a2335d9de052 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -1371,6 +1371,23 @@ void __init e820_reserve_resources(void) | |||
1371 | } | 1371 | } |
1372 | } | 1372 | } |
1373 | 1373 | ||
1374 | /* How much should we pad RAM ending depending on where it is? */ | ||
1375 | static unsigned long ram_alignment(resource_size_t pos) | ||
1376 | { | ||
1377 | unsigned long mb = pos >> 20; | ||
1378 | |||
1379 | /* To 64kB in the first megabyte */ | ||
1380 | if (!mb) | ||
1381 | return 64*1024; | ||
1382 | |||
1383 | /* To 1MB in the first 16MB */ | ||
1384 | if (mb < 16) | ||
1385 | return 1024*1024; | ||
1386 | |||
1387 | /* To 32MB for anything above that */ | ||
1388 | return 32*1024*1024; | ||
1389 | } | ||
1390 | |||
1374 | void __init e820_reserve_resources_late(void) | 1391 | void __init e820_reserve_resources_late(void) |
1375 | { | 1392 | { |
1376 | int i; | 1393 | int i; |
@@ -1382,6 +1399,24 @@ void __init e820_reserve_resources_late(void) | |||
1382 | insert_resource_expand_to_fit(&iomem_resource, res); | 1399 | insert_resource_expand_to_fit(&iomem_resource, res); |
1383 | res++; | 1400 | res++; |
1384 | } | 1401 | } |
1402 | |||
1403 | /* | ||
1404 | * Try to bump up RAM regions to reasonable boundaries to | ||
1405 | * avoid stolen RAM: | ||
1406 | */ | ||
1407 | for (i = 0; i < e820.nr_map; i++) { | ||
1408 | struct e820entry *entry = &e820_saved.map[i]; | ||
1409 | resource_size_t start, end; | ||
1410 | |||
1411 | if (entry->type != E820_RAM) | ||
1412 | continue; | ||
1413 | start = entry->addr + entry->size; | ||
1414 | end = round_up(start, ram_alignment(start)); | ||
1415 | if (start == end) | ||
1416 | continue; | ||
1417 | reserve_region_with_split(&iomem_resource, start, | ||
1418 | end - 1, "RAM buffer"); | ||
1419 | } | ||
1385 | } | 1420 | } |
1386 | 1421 | ||
1387 | char *__init default_machine_specific_memory_setup(void) | 1422 | char *__init default_machine_specific_memory_setup(void) |