diff options
author | Andi Kleen <ak@suse.de> | 2006-11-14 16:57:46 +0100 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-11-14 16:57:46 +0100 |
commit | 5e58a02a8f6a7a1c9ae41f39286bcd3aea0d6f24 (patch) | |
tree | dc2f2a8a695a14b7360bb0870e59646b9c7fdb17 /arch/x86_64 | |
parent | 51d67a488b53a5cc8401460480c124eaec71e2d4 (diff) | |
download | lwn-5e58a02a8f6a7a1c9ae41f39286bcd3aea0d6f24.tar.gz lwn-5e58a02a8f6a7a1c9ae41f39286bcd3aea0d6f24.zip |
[PATCH] x86-64: Handle reserve_bootmem_generic beyond end_pfn
This can happen on kexec kernels with some configurations, in particularly
on Unisys ES7000 systems.
Analysis by Amul Shah
Cc: Amul Shah <amul.shah@unisys.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/mm/init.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 971dc1181e69..f1f977aafae1 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -655,9 +655,22 @@ void free_initrd_mem(unsigned long start, unsigned long end) void __init reserve_bootmem_generic(unsigned long phys, unsigned len) { - /* Should check here against the e820 map to avoid double free */ #ifdef CONFIG_NUMA int nid = phys_to_nid(phys); +#endif + unsigned long pfn = phys >> PAGE_SHIFT; + if (pfn >= end_pfn) { + /* This can happen with kdump kernels when accessing firmware + tables. */ + if (pfn < end_pfn_map) + return; + printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n", + phys, len); + return; + } + + /* Should check here against the e820 map to avoid double free */ +#ifdef CONFIG_NUMA reserve_bootmem_node(NODE_DATA(nid), phys, len); #else reserve_bootmem(phys, len); |