summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-11-14 18:57:46 +0300
committerAndi Kleen <andi@basil.nowhere.org>2006-11-14 18:57:46 +0300
commit5e58a02a8f6a7a1c9ae41f39286bcd3aea0d6f24 (patch)
treedc2f2a8a695a14b7360bb0870e59646b9c7fdb17 /arch
parent51d67a488b53a5cc8401460480c124eaec71e2d4 (diff)
downloadlinux-5e58a02a8f6a7a1c9ae41f39286bcd3aea0d6f24.tar.xz
[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')
-rw-r--r--arch/x86_64/mm/init.c15
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);