This patch sync the behavior of user space kexec and kexec_file_load,
they will both fill the boot_params.acpi_rsdp_addr with a valid RSDP
value, to make sure second kernel can always get the RSDP consistently.
This will make it effortless to boot newer version of kernel (5.0+)
without specifying acpi_rsdp= cmdline on EFI system even with EFI
service disabled. Should not change any behavior with older kernels.
Backport the following commits from upstream:
commit 40805e393b2fc84551a6705e1890e995e3ee8320
Author: Kairui Song <kasong(a)redhat.com>
crashdump/x86: Use new introduce helper for getting RSDP
commit b071fc084bdafd4674cd776581cab2bf2b44a004
Author: Kairui Song <kasong(a)redhat.com>
x86: Always try to fill acpi_rsdp_addr in boot params
commit cedeee0a30075030632a18e419419371ddf3fca3
Author: Kairui Song <kasong(a)redhat.com>
x86: Introduce helpers for getting RSDP address
commit 402351390f31b2db0768eef4ced375d00bff9e17
Author: Kairui Song <kasong(a)redhat.com>
x86: Update boot parameters defination
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
...o-fill-acpi_rsdp_addr-in-boot-params.patch | 272 ++++++++++++++++++
kexec-tools.spec | 4 +-
2 files changed, 275 insertions(+), 1 deletion(-)
create mode 100644 kexec-tools-2.0.19-always-try-to-fill-acpi_rsdp_addr-in-boot-params.patch
diff --git a/kexec-tools-2.0.19-always-try-to-fill-acpi_rsdp_addr-in-boot-params.patch b/kexec-tools-2.0.19-always-try-to-fill-acpi_rsdp_addr-in-boot-params.patch
new file mode 100644
index 0000000..c9f6459
--- /dev/null
+++ b/kexec-tools-2.0.19-always-try-to-fill-acpi_rsdp_addr-in-boot-params.patch
@@ -0,0 +1,272 @@
+From f9bfb3d112ee4ba7566bc07d744cb356e4383254 Mon Sep 17 00:00:00 2001
+From: Kairui Song <kasong(a)redhat.com>
+Date: Fri, 24 May 2019 14:23:18 +0800
+Subject: [PATCH] x86: Always try to fill acpi_rsdp_addr in boot params
+
+This is squash of following commits:
+
+commit 40805e393b2fc84551a6705e1890e995e3ee8320
+Author: Kairui Song <kasong(a)redhat.com>
+Date: Fri May 24 14:23:21 2019 +0800
+
+ crashdump/x86: Use new introduce helper for getting RSDP
+
+ Use the new introduce helper for getting RSDP, this ensures RSDP is
+ always accessible and avoid code duplication.
+
+ Signed-off-by: Kairui Song <kasong(a)redhat.com>
+ Signed-off-by: Simon Horman <horms(a)verge.net.au>
+
+commit b071fc084bdafd4674cd776581cab2bf2b44a004
+Author: Kairui Song <kasong(a)redhat.com>
+Date: Fri May 24 14:23:20 2019 +0800
+
+ x86: Always try to fill acpi_rsdp_addr in boot params
+
+ Since kernel commit e6e094e053af75 ("x86/acpi, x86/boot: Take RSDP address
+ from boot params if available"), kernel accept an acpi_rsdp_addr param in
+ boot_params. So fill in this parameter unconditionally, ensure second
+ kernel always get the right RSDP address consistently, and boot well on
+ EFI system even with EFI service disabled. User no longer need to change
+ the kernel cmdline to workaround the missing RSDP issue.
+
+ For older version of kernels (Before 5.0), there won't be any change of
+ behavior.
+
+ Signed-off-by: Kairui Song <kasong(a)redhat.com>
+ Signed-off-by: Simon Horman <horms(a)verge.net.au>
+
+commit cedeee0a30075030632a18e419419371ddf3fca3
+Author: Kairui Song <kasong(a)redhat.com>
+Date: Fri May 24 14:23:19 2019 +0800
+
+ x86: Introduce helpers for getting RSDP address
+
+ On x86 RSDP is fundamental for booting the machine. When second kernel
+ is incapable of parsing the RSDP address (eg. kexec next kernel on an EFI
+ system with EFI service disabled), kexec should prepare the RSDP address
+ for second kernel.
+
+ Introduce helpers for getting RSDP from multiple sources, including boot
+ params and EFI firmware.
+
+ For legacy BIOS interface, there is no better way to find the RSDP address
+ rather than scanning the memory region and search for it, and this will
+ always be done by the kernel as a fallback, so this is no need to try to
+ get the RSDP address for that case.
+
+ Signed-off-by: Kairui Song <kasong(a)redhat.com>
+ Signed-off-by: Simon Horman <horms(a)verge.net.au>
+
+commit 402351390f31b2db0768eef4ced375d00bff9e17
+Author: Kairui Song <kasong(a)redhat.com>
+Date: Fri May 24 14:23:18 2019 +0800
+
+ x86: Update boot parameters defination
+
+ Since kernel commit e6e094e053af75 ("x86/acpi, x86/boot: Take RSDP address
+ from boot params if available"), kernel accept a acpi_rsdp_addr param in
+ boot_params. Sync the x86_linux_param_header to support this param.
+
+ Signed-off-by: Kairui Song <kasong(a)redhat.com>
+ Signed-off-by: Simon Horman <horms(a)verge.net.au>
+---
+ include/x86/x86-linux.h | 6 +++--
+ kexec/arch/i386/crashdump-x86.c | 34 +++++++----------------
+ kexec/arch/i386/kexec-x86-common.c | 43 ++++++++++++++++++++++++++++++
+ kexec/arch/i386/kexec-x86.h | 1 +
+ kexec/arch/i386/x86-linux-setup.c | 6 +++--
+ kexec/arch/i386/x86-linux-setup.h | 1 +
+ 6 files changed, 62 insertions(+), 29 deletions(-)
+
+diff --git a/include/x86/x86-linux.h b/include/x86/x86-linux.h
+index 352ea02..9646102 100644
+--- a/include/x86/x86-linux.h
++++ b/include/x86/x86-linux.h
+@@ -45,7 +45,6 @@ struct apm_bios_info {
+ uint16_t cseg_len; /* 0x4e */
+ uint16_t cseg_16_len; /* 0x50 */
+ uint16_t dseg_len; /* 0x52 */
+- uint8_t reserved[44]; /* 0x54 */
+ };
+
+ /*
+@@ -113,12 +112,15 @@ struct x86_linux_param_header {
+ uint8_t reserved4[2]; /* 0x3e -- 0x3f reserved for future expansion */
+
+ struct apm_bios_info apm_bios_info; /* 0x40 */
++ uint8_t reserved4_1[28]; /* 0x54 */
++ uint64_t acpi_rsdp_addr; /* 0x70 */
++ uint8_t reserved4_2[8]; /* 0x78 */
+ struct drive_info_struct drive_info; /* 0x80 */
+ struct sys_desc_table sys_desc_table; /* 0xa0 */
+ uint32_t ext_ramdisk_image; /* 0xc0 */
+ uint32_t ext_ramdisk_size; /* 0xc4 */
+ uint32_t ext_cmd_line_ptr; /* 0xc8 */
+- uint8_t reserved4_1[0x1c0 - 0xcc]; /* 0xe4 */
++ uint8_t reserved4_3[0x1c0 - 0xcc]; /* 0xe4 */
+ uint8_t efi_info[32]; /* 0x1c0 */
+ uint32_t alt_mem_k; /* 0x1e0 */
+ uint8_t reserved5[4]; /* 0x1e4 */
+diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
+index 140f45b..a2aea31 100644
+--- a/kexec/arch/i386/crashdump-x86.c
++++ b/kexec/arch/i386/crashdump-x86.c
+@@ -787,35 +787,19 @@ static int sysfs_efi_runtime_map_exist(void)
+ /* 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=";
++ uint64_t acpi_rsdp;
++ char acpi_rsdp_buf[MAX_LINE];
+
+- fp = fopen("/sys/firmware/efi/systab", "r");
+- if (!fp)
+- return;
++ acpi_rsdp = get_acpi_rsdp();
+
+- 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);
++ if (!acpi_rsdp)
++ return;
+
+- break;
+- }
+- }
++ sprintf(acpi_rsdp_buf, " acpi_rsdp=0x%lx", acpi_rsdp);
++ if (strlen(cmdline) + strlen(acpi_rsdp_buf) > (COMMAND_LINE_SIZE - 1))
++ die("Command line overflow\n");
+
+- fclose(fp);
++ strcat(cmdline, acpi_rsdp_buf);
+ }
+
+ static void get_backup_area(struct kexec_info *info,
+diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
+index de99758..5c55ec8 100644
+--- a/kexec/arch/i386/kexec-x86-common.c
++++ b/kexec/arch/i386/kexec-x86-common.c
+@@ -39,6 +39,7 @@
+ #include "../../firmware_memmap.h"
+ #include "../../crashdump.h"
+ #include "kexec-x86.h"
++#include "x86-linux-setup.h"
+ #include "../../kexec-xen.h"
+
+ /* Used below but not present in (older?) xenctrl.h */
+@@ -392,4 +393,46 @@ int get_memory_ranges(struct memory_range **range, int *ranges,
+ return ret;
+ }
+
++static uint64_t bootparam_get_acpi_rsdp(void) {
++ uint64_t acpi_rsdp = 0;
++ off_t offset = offsetof(struct x86_linux_param_header, acpi_rsdp_addr);
+
++ if (get_bootparam(&acpi_rsdp, offset, sizeof(acpi_rsdp)))
++ return 0;
++
++ return acpi_rsdp;
++}
++
++static uint64_t efi_get_acpi_rsdp(void) {
++ FILE *fp;
++ char line[MAX_LINE], *s;
++ uint64_t acpi_rsdp = 0;
++
++ fp = fopen("/sys/firmware/efi/systab", "r");
++ if (!fp)
++ return acpi_rsdp;
++
++ while(fgets(line, sizeof(line), fp) != 0) {
++ /* ACPI20= always goes before ACPI= */
++ if ((strstr(line, "ACPI20=")) || (strstr(line, "ACPI="))) {
++ s = strchr(line, '=') + 1;
++ sscanf(s, "0x%lx", &acpi_rsdp);
++ break;
++ }
++ }
++ fclose(fp);
++
++ return acpi_rsdp;
++}
++
++uint64_t get_acpi_rsdp(void)
++{
++ uint64_t acpi_rsdp = 0;
++
++ acpi_rsdp = bootparam_get_acpi_rsdp();
++
++ if (!acpi_rsdp)
++ acpi_rsdp = efi_get_acpi_rsdp();
++
++ return acpi_rsdp;
++}
+diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h
+index c2bcd37..1b58c3b 100644
+--- a/kexec/arch/i386/kexec-x86.h
++++ b/kexec/arch/i386/kexec-x86.h
+@@ -86,4 +86,5 @@ int nbi_load(int argc, char **argv, const char *buf, off_t len,
+ void nbi_usage(void);
+
+ extern unsigned xen_e820_to_kexec_type(uint32_t type);
++extern uint64_t get_acpi_rsdp(void);
+ #endif /* KEXEC_X86_H */
+diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
+index b643c8b..057ee14 100644
+--- a/kexec/arch/i386/x86-linux-setup.c
++++ b/kexec/arch/i386/x86-linux-setup.c
+@@ -123,7 +123,6 @@ void setup_linux_bootloader_parameters_high(
+ cmdline_ptr[cmdline_len - 1] = '\0';
+ }
+
+-static int get_bootparam(void *buf, off_t offset, size_t size);
+ static int setup_linux_vesafb(struct x86_linux_param_header *real_mode)
+ {
+ struct fb_fix_screeninfo fix;
+@@ -460,7 +459,7 @@ char *find_mnt_by_type(char *type)
+ return mntdir;
+ }
+
+-static int get_bootparam(void *buf, off_t offset, size_t size)
++int get_bootparam(void *buf, off_t offset, size_t size)
+ {
+ int data_file;
+ char *debugfs_mnt, *sysfs_mnt;
+@@ -910,4 +909,7 @@ void setup_linux_system_parameters(struct kexec_info *info,
+
+ /* fill the EDD information */
+ setup_edd_info(real_mode);
++
++ /* Always try to fill acpi_rsdp_addr */
++ real_mode->acpi_rsdp_addr = get_acpi_rsdp();
+ }
+diff --git a/kexec/arch/i386/x86-linux-setup.h b/kexec/arch/i386/x86-linux-setup.h
+index f5d23d3..0c651e5 100644
+--- a/kexec/arch/i386/x86-linux-setup.h
++++ b/kexec/arch/i386/x86-linux-setup.h
+@@ -21,6 +21,7 @@ static inline void setup_linux_bootloader_parameters(
+ }
+ void setup_linux_system_parameters(struct kexec_info *info,
+ struct x86_linux_param_header *real_mode);
++int get_bootparam(void *buf, off_t offset, size_t size);
+
+
+ #define SETUP_BASE 0x90000
+--
+2.21.0
+
diff --git a/kexec-tools.spec b/kexec-tools.spec
index b642543..5a050e8 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -76,6 +76,7 @@ Obsoletes: diskdumputils netdump kexec-tools-eppic
# Patches 101 through 200 are meant for x86_64 kexec-tools enablement
#
Patch101: kexec-tools-2.0.19-makedumpfiles-x86_64-Add-support-for-AMD-Secure-Memory-Encry.patch
+Patch102: kexec-tools-2.0.19-always-try-to-fill-acpi_rsdp_addr-in-boot-params.patch
#
# Patches 301 through 400 are meant for ppc64 kexec-tools enablement
@@ -107,8 +108,9 @@ mkdir -p -m755 kcp
tar -z -x -v -f %{SOURCE9}
tar -z -x -v -f %{SOURCE19}
-%patch601 -p1
%patch101 -p1
+%patch102 -p1
+%patch601 -p1
%ifarch ppc
%define archdef ARCH=ppc
--
2.21.0