Sophie

Sophie

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

kernel-2.6.18-194.11.1.el5.src.rpm

From: Prarit Bhargava <prarit@redhat.com>
Date: Mon, 9 Jun 2008 15:04:49 -0400
Subject: [x86_64] memmap flag results in bogus RAM map output
Message-id: 20080609190347.30654.67827.sendpatchset@prarit.bos.redhat.com
O-Subject: [RHEL5 PATCH]: memmap flag results in bogus RAM map output
Bugzilla: 450244
RH-Acked-by: Larry Woodman <lwoodman@redhat.com>
RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com>

Backport of

http://marc.info/?l=linux-kernel&m=119040942802966&w=2

Before patch:

user-defined physical RAM map:
 user: 0000000000000000 - 000000000009ec00 (usable)
 user: 000000000009ec00 - 00000000000a0000 (reserved)
 user: 00000000000e8000 - 0000000000100000 (reserved)
 user: 0000000000100000 - 00000000cffc2e40 (usable)
 user: 00000000cffc2e40 - 00000000d0000000 (reserved)
 user: 00000000e0000000 - 00000000f0000000 (reserved)
 user: 00000000fec00000 - 0000000100000000 (reserved)
 user: 0000000100000000 - 0000000130000000 (usable)
 user: 000000005f600000 - 000000007f600000 (reserved)

Last entry contradicts 4th entry.

After patch:

user-defined physical RAM map:
 user: 0000000000000000 - 000000000009ec00 (usable)
 user: 000000000009ec00 - 00000000000a0000 (reserved)
 user: 00000000000e8000 - 0000000000100000 (reserved)
 user: 0000000000100000 - 000000005f600000 (usable)
 user: 000000005f600000 - 000000007f600000 (reserved)
 user: 000000007f600000 - 00000000cffc2e40 (usable)
 user: 00000000cffc2e40 - 00000000d0000000 (reserved)
 user: 00000000e0000000 - 00000000f0000000 (reserved)
 user: 00000000fec00000 - 0000000100000000 (reserved)
 user: 0000000100000000 - 0000000130000000 (usable)

Fifth entry is correct.

Resolves BZ 450244.

Successfully tested and compiled by me.

diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 5c56cf1..52b313c 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -651,12 +651,34 @@ void __init parse_memopt(char *p, char **from)
 	end_user_pfn >>= PAGE_SHIFT;	
 } 
 
+static int userdef __initdata;
+
 void __init parse_memmapopt(char *p, char **from)
 {
+	char *oldp;
 	unsigned long long start_at, mem_size;
 
-	mem_size = memparse(p, from);
-	p = *from;
+	if (!strcmp(p, "exactmap")) {
+#ifdef CONFIG_CRASH_DUMP
+		/*
+		 * If we are doing a crash dump, we still need to know
+		 * the real mem size before original memory map is
+		 * reset.
+		 */
+		saved_max_pfn = e820_end_of_ram();
+#endif
+		end_pfn_map = 0;
+		e820.nr_map = 0;
+		userdef = 1;
+		return;
+	}
+
+	oldp = p;
+	mem_size = memparse(p, &p);
+	if (p == oldp)
+		return;
+
+	userdef = 1;
 	if (*p == '@') {
 		start_at = memparse(p+1, from);
 		add_memory_region(start_at, mem_size, E820_RAM);
@@ -672,6 +694,19 @@ void __init parse_memmapopt(char *p, char **from)
 	p = *from;
 }
 
+void __init finish_e820_parsing(void)
+{
+	if (userdef) {
+		char nr = e820.nr_map;
+
+		sanitize_e820_map(e820.map, &nr);
+		e820.nr_map = nr;
+
+		printk(KERN_INFO "user-defined physical RAM map:\n");
+		e820_print_map("user");
+	}
+}
+
 unsigned long pci_mem_start = 0xaeedbabe;
 EXPORT_SYMBOL(pci_mem_start);
 
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 19ca938..afef71b 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -290,7 +290,6 @@ static __init void parse_cmdline_early (char ** cmdline_p)
 {
 	char c = ' ', *to = command_line, *from = COMMAND_LINE;
 	int len = 0;
-	int userdef = 0;
 
 	for (;;) {
 		if (c != ' ') 
@@ -371,25 +370,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
 			parse_memopt(from+4, &from); 
 
 		if (!memcmp(from, "memmap=", 7)) {
-			/* exactmap option is for used defined memory */
-			if (!memcmp(from+7, "exactmap", 8)) {
-#ifdef CONFIG_CRASH_DUMP
-				/* If we are doing a crash dump, we
-				 * still need to know the real mem
-				 * size before original memory map is
-				 * reset.
-				 */
-				saved_max_pfn = e820_end_of_ram();
-#endif
-				from += 8+7;
-				end_pfn_map = 0;
-				e820.nr_map = 0;
-				userdef = 1;
-			}
-			else {
-				parse_memmapopt(from+7, &from);
-				userdef = 1;
-			}
+			parse_memmapopt(from+7, &from);
 		}
 
 #ifdef CONFIG_NUMA
@@ -447,10 +428,6 @@ static __init void parse_cmdline_early (char ** cmdline_p)
 			break;
 		*(to++) = c;
 	}
-	if (userdef) {
-		printk(KERN_INFO "user-defined physical RAM map:\n");
-		e820_print_map("user");
-	}
 	*to = '\0';
 	*cmdline_p = command_line;
 }
@@ -552,6 +529,8 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_cmdline_early(cmdline_p);
 
+	finish_e820_parsing();
+
 	early_identify_cpu(&boot_cpu_data);
 
 	/*
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h
index f656748..eaf2103 100644
--- a/include/asm-x86_64/e820.h
+++ b/include/asm-x86_64/e820.h
@@ -59,6 +59,8 @@ extern unsigned long e820_hole_size(unsigned long start_pfn,
 extern void __init parse_memopt(char *p, char **end);
 extern void __init parse_memmapopt(char *p, char **end);
 
+extern void __init finish_e820_parsing(void);
+
 extern struct e820map e820;
 
 extern unsigned ebda_addr, ebda_size;