summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Young <dyoung@redhat.com>2012-10-18 11:16:08 +0800
committerSimon Horman <horms@verge.net.au>2012-10-19 10:33:17 +0900
commit75d1a16f0b4e5b33e91a51d93014f1fd8303f36e (patch)
tree42ce4b3a72943d72fa7f29c70593d3e32c8acdb7
parentaaedd5321b239a919a080da84ed5c96fb4481ed2 (diff)
downloadkexec-tools-75d1a16f0b4e5b33e91a51d93014f1fd8303f36e.tar.gz
kdump: pass acpi_rsdp= to 2nd kernel for efi booting
In case efi booting, kdump need kernel parameter acpi_rsdp= to retrieve the acpi root table physical address. Add a function cmdline_add_efi to get the address from /sys/firmware/efi/systab If there's no such file or read fail the function will just do nothing. Tested efi boot Fedora 17 on thinkpad T420. Some background info for this issue: http://lists.infradead.org/pipermail/kexec/2010-March/003889.html [v1 -> v2]: Address comments from Khalid and Simon use fgets instead of read(2) to iterate the file do not add 'noefi' because kexec does not construct EFI signature in bootloader signature in boot_params, so kexec'd kernel will disable EFI automatically even without noefi. Signed-off-by: Dave Young <dyoung@redhat.com> Reviewed-by: Khalid Aziz <khalid@gonehiking.org> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--kexec/arch/i386/crashdump-x86.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index 09c3fd4a..245402c2 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -835,6 +835,40 @@ static int cmdline_add_memmap_acpi(char *cmdline, unsigned long start,
return 0;
}
+/* Appends 'acpi_rsdp=' commandline for efi boot crash dump */
+static void cmdline_add_efi(char *cmdline)
+{
+ FILE *fp;
+ int cmdlen, len;
+ char line[MAX_LINE], *s;
+ const char *acpis = " acpi_rsdp=";
+
+ fp = fopen("/sys/firmware/efi/systab", "r");
+ if (!fp)
+ return;
+
+ while(fgets(line, sizeof(line), fp) != 0) {
+ /* ACPI20= always goes before ACPI= */
+ if ((strstr(line, "ACPI20=")) || (strstr(line, "ACPI="))) {
+ line[strlen(line) - 1] = '\0';
+ s = strchr(line, '=');
+ s += 1;
+ len = strlen(s) + strlen(acpis);
+ cmdlen = strlen(cmdline) + len;
+ if (cmdlen > (COMMAND_LINE_SIZE - 1))
+ die("Command line overflow\n");
+ strcat(cmdline, acpis);
+ strcat(cmdline, s);
+ dbgprintf("Command line after adding efi\n");
+ dbgprintf("%s\n", cmdline);
+
+ break;
+ }
+ }
+
+ fclose(fp);
+}
+
static void get_backup_area(struct kexec_info *info,
struct memory_range *range, int ranges)
{
@@ -998,6 +1032,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
if (delete_memmap(memmap_p, elfcorehdr, memsz) < 0)
return -1;
cmdline_add_memmap(mod_cmdline, memmap_p);
+ cmdline_add_efi(mod_cmdline);
cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
/* Inform second kernel about the presence of ACPI tables. */