From: Cliff Wickman <cpw@xxxxxxx> The crash kernel is not able to find its root device if that device is not on PCI 0. This is because it is booted with the command line option memmap=exactmap which currently clears the e820 table and does not restore reserved spaces. This works for a device on PCI 0 because ACPI falls back to a legacy mode. But the error message " [Firmware Bug]: PCI: MMCONFIG at [mem 0x80000000-0x80cfffff] not reserved in ACPI motherboard resources" is written to the log even in this functioning case. It fails for some devices on UV2, and only for UV2, because SGI seems to be the only manufacturer currently using the extended PCI(>0). The fix is simple, as long as the command line is long enough to include all the reserved spaces. The command line may have to be lengthened. See [PATCH] kexec: lengthen the kernel command line image Signed-off-by: Cliff Wickman <cpw at sgi.com> --- kexec/arch/i386/crashdump-x86.c | 43 ++++++++++++++++++++++++++++++++++++++-- kexec/kexec-syscall.h | 2 - 2 files changed, 42 insertions(+), 3 deletions(-) Index: kexec-tools-2.0.3/kexec/arch/i386/crashdump-x86.c =================================================================== --- kexec-tools-2.0.3.orig/kexec/arch/i386/crashdump-x86.c +++ kexec-tools-2.0.3/kexec/arch/i386/crashdump-x86.c @@ -236,6 +236,8 @@ static int get_crash_memory_ranges(struc type = RANGE_ACPI; } else if(memcmp(str,"ACPI Non-volatile Storage\n",26) == 0 ) { type = RANGE_ACPI_NVS; + } else if(memcmp(str,"reserved\n", 9) == 0 ) { + type = RANGE_RESERVED; } else if (memcmp(str, "GART\n", 5) == 0) { gart_start = start; gart_end = end; @@ -708,6 +710,39 @@ static void get_backup_area(unsigned lon fclose(fp); } +/* Appends memmap=X$Y commandline for reserved memory to command line*/ +static int cmdline_add_memmap_reserved(char *cmdline, unsigned long start, + unsigned long end) +{ + int cmdlen, len, align = 1024; + unsigned long startk, endk; + char str_mmap[256], str_tmp[20]; + + if (!(end - start)) + return 0; + + startk = start/1024; + endk = (end + align - 1)/1024; + strcpy (str_mmap, " memmap="); + ultoa((endk - startk), str_tmp); + strcat (str_mmap, str_tmp); + strcat (str_mmap, "K$"); + ultoa(startk, str_tmp); + strcat (str_mmap, str_tmp); + strcat (str_mmap, "K"); + len = strlen(str_mmap); + cmdlen = strlen(cmdline) + len; + if (cmdlen > (COMMAND_LINE_SIZE - 1)) + die("Command line overflow\n"); + strcat(cmdline, str_mmap); + +#ifdef DEBUG + printf("Command line after adding reserved memmap\n"); + printf("%s\n", cmdline); +#endif + return 0; +} + /* Loads additional segments in case of a panic kernel is being loaded. * One segment for backup region, another segment for storing elf headers * for crash memory image. @@ -844,11 +879,15 @@ int load_crashdump_segments(struct kexec for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { unsigned long start, end; if ( !( mem_range[i].type == RANGE_ACPI - || mem_range[i].type == RANGE_ACPI_NVS) ) + || mem_range[i].type == RANGE_ACPI_NVS + || mem_range[i].type == RANGE_RESERVED) ) continue; start = mem_range[i].start; end = mem_range[i].end; - cmdline_add_memmap_acpi(mod_cmdline, start, end); + if (mem_range[i].type == RANGE_RESERVED) + cmdline_add_memmap_reserved(mod_cmdline, start, end); + else + cmdline_add_memmap_acpi(mod_cmdline, start, end); } return 0; } Index: kexec-tools-2.0.3/kexec/kexec-syscall.h =================================================================== --- kexec-tools-2.0.3.orig/kexec/kexec-syscall.h +++ kexec-tools-2.0.3/kexec/kexec-syscall.h @@ -96,7 +96,7 @@ static inline long kexec_reboot(void) #define KEXEC_ARCH_MIPS ( 8 << 16) #define KEXEC_ARCH_CRIS (76 << 16) -#define KEXEC_MAX_SEGMENTS 16 +#define KEXEC_MAX_SEGMENTS 70 #ifdef __i386__ #define KEXEC_ARCH_NATIVE KEXEC_ARCH_386