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;