From: Larry Woodman <lwoodman@redhat.com> Date: Thu, 2 Oct 2008 12:02:17 -0400 Subject: [x86] PAE: limit RAM to 64GB/PAE36 Message-id: 1222963337.22762.32.camel@dhcp-100-19-198.bos.redhat.com O-Subject: [RHEL5 patch] Prevent panic on boot by limiting RAM to 64GB/PAE36 on 32-bit/x86 systems Bugzilla: 465373 RH-Acked-by: Dave Anderson <anderson@redhat.com> We ran into a strange problem during hardware certification testing recently. While performing RHEL4 hardware cert tests in a 96GB x86_64 system it was noticed that the x86/32-bit hugemem kernel boots and runs successfully with all 96GB of RAM. Originally x86 RAM sizes were limited to 36 bits via PAE36 while x86_64 systems supported 40 bits via PAE40. Evidently PAE40 works in 32-bit compatibility mode since more than 64GB of RAM runs fine when an x86_64 system runs an x86 kernel. ------------------------------------------------------------ BIOS-provided physical RAM map: BIOS-e820: 0000000000000000 - 00000000000a0000 (usable) BIOS-e820: 0000000000100000 - 00000000cfaa0000 (usable) BIOS-e820: 00000000cfaa0000 - 00000000cfab6000 (reserved) BIOS-e820: 00000000cfab6000 - 00000000cfad5c00 (ACPI data) BIOS-e820: 00000000cfad5c00 - 00000000d0000000 (reserved) BIOS-e820: 00000000f0000000 - 00000000f8000000 (reserved) BIOS-e820: 00000000fe000000 - 0000000100000000 (reserved) BIOS-e820: 0000000100000000 - 0000001830000000 (usable) 98176MB HIGHMEM available. 896MB LOWMEM available. ------------------------------------------------------------ Everything seems to work OK in RHEL4 because the hugemem kernel has enough lowmem to fit the mem_map of system with this much RAM. The problem exists with RHEL5. Since RHEL5 has no hugemem kernel and mem_map is too large to fit in lowmem of the PAE kernel, a large memory x86_64 system will panic when booting the 32-bit PAE kernel. While this is not a critical issue because we do not officially support 32-bit systems with huge amounts of RAM and its doubtful that customers will do this, it is a regression from RHEL4 to RHEL5. A simple fix is to limit the x86 memory size to 64GB by obeying PAE36. ------------------------------------------------------------------------ BIOS-provided physical RAM map: BIOS-e820: 0000000000000000 - 000000000009d800 (usable) BIOS-e820: 000000000009d800 - 00000000000a0000 (reserved) BIOS-e820: 00000000000ce000 - 0000000000100000 (reserved) BIOS-e820: 0000000000100000 - 0000000037e70000 (usable) BIOS-e820: 0000000037e70000 - 0000000037ed8000 (ACPI data) BIOS-e820: 0000000037ed8000 - 0000000037f00000 (ACPI NVS) BIOS-e820: 0000000037f00000 - 00000000f0000000 (usable) BIOS-e820: 00000000f8000000 - 00000000fec00000 (reserved) BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved) BIOS-e820: 0000000100000000 - 0000002008000000 (usable) RAM exceeds maximum supported memory for x86, Truncating to 64GB 64640MB HIGHMEM available. 896MB LOWMEM available. ------------------------------------------------------------------------ diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 98e936d..6b65d8f 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1017,6 +1017,7 @@ e820_all_mapped(unsigned long s, unsigned long e, unsigned type) return 0; } +#define MAX_PAE36_PFN 1024*1024*16 /* * Find the highest page frame number we have available */ @@ -1044,6 +1045,10 @@ void __init find_max_pfn(void) max_pfn = end; memory_present(0, start, end); } + if (max_pfn > MAX_PAE36_PFN) { + printk("RAM exceeds maximum supported memory for x86, Truncating to 64GB\n"); + max_pfn = MAX_PAE36_PFN; + } } /*