Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4132

kernel-2.6.18-194.11.1.el5.src.rpm

From: Vivek Goyal <vgoyal@redhat.com>
Subject: [PATCH][RHEL5] BZ#215417: x86_64: kdump mptable reservation fix on  unisys es7000 machines
Date: Tue, 28 Nov 2006 14:17:36 -0500
Bugzilla: 215417
Message-Id: <456C8B50.5040305@redhat.com>
Changelog: x86_64: kdump mptable reservation fix 


Hi,

This patch fixes a issue with kdump on unisys ES7000 machines. 
Basically, on ES7000 machines, mptables are not located in first 640K 
instead there are located somewhere too high in the memory (Because of 
MP tables being too big, ~240K). Kernel tries to reserve that memory but 
panics because second kernel boots from a very limited memory area and 
does not even see that physical memory.

This patch sorts of checks, if the pfn you trying to reserve, then give 
a warning but continue.

This patch is already upstream in 2.6.19-rc6. Patch was attached to the 
bug by Amul Shah. I have just taken that patch and posting it here so 
that RHEL5 kenrels can have it.

Thanks
Vivek



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>
---

 arch/x86_64/mm/init.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff -puN arch/x86_64/mm/init.c~kdump_mptables_to_high_andikleen arch/x86_64/mm/init.c
--- linux-2.6.18.x86_64-2747/arch/x86_64/mm/init.c~kdump_mptables_to_high_andikleen	2006-11-27 21:01:38.000000000 -0500
+++ linux-2.6.18.x86_64-2747-root/arch/x86_64/mm/init.c	2006-11-27 21:02:50.000000000 -0500
@@ -754,9 +754,22 @@ void free_initrd_mem(unsigned long start
 
 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);    
_