summaryrefslogtreecommitdiff
path: root/kexec/arch/i386/kexec-x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/i386/kexec-x86.c')
-rw-r--r--kexec/arch/i386/kexec-x86.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/kexec/arch/i386/kexec-x86.c b/kexec/arch/i386/kexec-x86.c
index 1159686..41a0985 100644
--- a/kexec/arch/i386/kexec-x86.c
+++ b/kexec/arch/i386/kexec-x86.c
@@ -37,7 +37,8 @@
static struct memory_range memory_range[MAX_MEMORY_RANGES];
/* Return a sorted list of memory ranges. */
-int get_memory_ranges(struct memory_range **range, int *ranges)
+int get_memory_ranges(struct memory_range **range, int *ranges,
+ unsigned long kexec_flags)
{
const char iomem[]= "/proc/iomem";
int memory_ranges = 0;
@@ -79,6 +80,20 @@ int get_memory_ranges(struct memory_range **range, int *ranges)
else if (memcmp(str, "ACPI Non-volatile Storage\n", 26) == 0) {
type = RANGE_ACPI_NVS;
}
+ else if (memcmp(str, "Crash kernel\n", 13) == 0) {
+ /* Redefine the memory region boundaries if kernel
+ * exports the limits and if it is panic kernel.
+ * Override user values only if kernel exported values are
+ * subset of user defined values.
+ */
+ if (kexec_flags & KEXEC_ON_CRASH) {
+ if (start > mem_min)
+ mem_min = start;
+ if (end < mem_max)
+ mem_max = end;
+ }
+ continue;
+ }
else {
continue;
}
@@ -206,7 +221,7 @@ int arch_process_options(int argc, char **argv)
return 0;
}
-int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags)
+int arch_compat_trampoline(struct kexec_info *info)
{
int result;
struct utsname utsname;
@@ -224,11 +239,11 @@ int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags)
/* For compatibility with older patches
* use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_386 here.
*/
- *flags |= KEXEC_ARCH_DEFAULT;
+ info->kexec_flags |= KEXEC_ARCH_DEFAULT;
}
else if (strcmp(utsname.machine, "x86_64") == 0)
{
- *flags |= KEXEC_ARCH_X86_64;
+ info->kexec_flags |= KEXEC_ARCH_X86_64;
if (!info->rhdr.e_shdr) {
fprintf(stderr,
"A trampoline is required for cross architecture support\n");
@@ -249,6 +264,8 @@ int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags)
void arch_update_purgatory(struct kexec_info *info)
{
+ uint8_t panic_kernel = 0;
+
elf_rel_set_symbol(&info->rhdr, "reset_vga",
&arch_options.reset_vga, sizeof(arch_options.reset_vga));
elf_rel_set_symbol(&info->rhdr, "serial_base",
@@ -259,4 +276,11 @@ void arch_update_purgatory(struct kexec_info *info)
&arch_options.console_vga, sizeof(arch_options.console_vga));
elf_rel_set_symbol(&info->rhdr, "console_serial",
&arch_options.console_serial, sizeof(arch_options.console_serial));
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ panic_kernel = 1;
+ elf_rel_set_symbol(&info->rhdr, "backup_start",
+ &info->backup_start, sizeof(info->backup_start));
+ }
+ elf_rel_set_symbol(&info->rhdr, "panic_kernel",
+ &panic_kernel, sizeof(panic_kernel));
}