[PATCH 2.0.2] use /proc/iomem for map with "add_efi_memmap" kernel option

Ben Romer benjamin.romer at unisys.com
Wed Apr 27 08:56:09 EDT 2011


This patch changes the behavior of the kexec loader when the
"add_efi_memmap" option is present on the currently running kernel's
command line, to read the kernel memory map from /proc/iomem instead
of /sys/firmware/memmap. 

On EFI systems, sometimes the e820 table is missing or incomplete.
Systems like these use the "add_efi_memmap" option to add EFI's memory
table entries to the kernel's memory table to build a complete picture
of the system's memory; however, using the option does not add these
entries to the table used to populate /sys/firmware/memmap, which is
meant to be a pristine original copy. 

The kexec loader uses the pristine memory map by default, which causes
problems when the loader doesn't have a complete picture of the system
and incorrectly loads the kernel or ramdisk in places that aren't
actually usable. This change makes the kexec loader check the running
kernel's command line for the "add_efi_memmap" option and if it finds
it, will use the modified map instead of the original map.

signed-off-by: Benjamin Romer <benjamin.romer at unisys.com>
---

diff --git a/kexec/arch/i386/kexec-x86-common.c
b/kexec/arch/i386/kexec-x86-common.c
index ba54973..474e680 100644
--- a/kexec/arch/i386/kexec-x86-common.c
+++ b/kexec/arch/i386/kexec-x86-common.c
@@ -202,6 +202,28 @@ again:
 }
 
 /**
+ * Detect the add_efi_memmap kernel parameter.
+ *
+ * On some EFI-based systems, the e820 map is empty, or does not
contain a
+ * complete memory map. The add_efi_memmap parameter adds these entries
to
+ * the kernel's memory map, but does not add them under sysfs, which
causes
+ * kexec to fail in a way similar to how it does not work on Xen.
+ *
+ * @return 1 if parameter is present, 0 if not or if an error occurs.
+ */
+int efi_map_added( void ) {
+	char buf[512], *res;
+	FILE *fp = fopen( "/proc/cmdline", "r" );
+	if( fp ) {
+		res = fgets( buf, 512, fp );
+		fclose( fp );
+		return strstr( buf, "add_efi_memmap" ) != NULL;
+	} else {
+		return 0;
+	}
+}
+
+/**
  * Return a sorted list of memory ranges.
  *
  * If we have the /sys/firmware/memmap interface, then use that. If
not,
@@ -227,7 +249,7 @@ int get_memory_ranges(struct memory_range **range,
int *ranges,
 	 * even if we have /sys/firmware/memmap. Without that, /proc/vmcore
 	 * is empty in the kdump kernel.
 	 */
-	if (!xen_present() && have_sys_firmware_memmap()) {
+	if (!efi_map_added() && !xen_present() && have_sys_firmware_memmap())
{
 		ret = get_memory_ranges_sysfs(range, ranges);
 		if (!ret)
 			ret = fixup_memory_ranges_sysfs(range, ranges);





More information about the kexec mailing list