[PATCH 2/3] kexec: Pass panic message to crash_kexec()
From: Hidehiro Kawai <hidden>
Date: 2015-07-10 11:40:24
Also in:
kexec, linux-arm-kernel, linux-mips, linux-sh, lkml
Subsystem:
arm port, arm64 port (aarch64 architecture), kexec, linux for powerpc (32-bit and 64-bit), mips, s390 architecture, superh, the rest, x86 architecture (32-bit and 64-bit), x86 platform uv hpe superdome flex, x86 stack unwinding · Maintainers:
Russell King, Catalin Marinas, Will Deacon, Andrew Morton, Baoquan He, Mike Rapoport, Pasha Tatashin, Pratyush Yadav, Madhavan Srinivasan, Thomas Bogendoerfer, Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz, Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Steve Wahl, Josh Poimboeuf, Peter Zijlstra
Add an argument to crash_kexec() to pass the panic message. This patch is a preparation for the next patch, and it doesn't change the current behavior. Signed-off-by: Hidehiro Kawai <redacted> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Eric Biederman <redacted> Cc: Vivek Goyal <vgoyal@redhat.com> --- arch/arm/kernel/traps.c | 2 +- arch/arm64/kernel/traps.c | 2 +- arch/metag/kernel/traps.c | 2 +- arch/mips/kernel/traps.c | 2 +- arch/powerpc/kernel/traps.c | 2 +- arch/s390/kernel/ipl.c | 2 +- arch/sh/kernel/traps.c | 2 +- arch/x86/kernel/dumpstack.c | 2 +- arch/x86/platform/uv/uv_nmi.c | 2 +- include/linux/kexec.h | 7 +++++-- kernel/kexec.c | 23 ++++++++++++++++++++++- kernel/panic.c | 4 ++-- 12 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index d358226..abb7b86 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c@@ -293,7 +293,7 @@ static unsigned long oops_begin(void) static void oops_end(unsigned long flags, struct pt_regs *regs, int signr) { if (regs && kexec_should_crash(current)) - crash_kexec(regs); + crash_kexec_on_oops(regs, current); bust_spinlocks(0); die_owner = -1;
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 566bc4c..17a6841 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c@@ -233,7 +233,7 @@ void die(const char *str, struct pt_regs *regs, int err) ret = __die(str, err, thread, regs); if (regs && kexec_should_crash(thread->task)) - crash_kexec(regs); + crash_kexec_on_oops(regs, thread->task); bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
diff --git a/arch/metag/kernel/traps.c b/arch/metag/kernel/traps.c
index 17b2e2e..dca46c7 100644
--- a/arch/metag/kernel/traps.c
+++ b/arch/metag/kernel/traps.c@@ -110,7 +110,7 @@ void __noreturn die(const char *str, struct pt_regs *regs, bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); if (kexec_should_crash(current)) - crash_kexec(regs); + crash_kexec_on_oops(regs, current); if (in_interrupt()) panic("Fatal exception in interrupt");
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2a7b38e..46fc9a6 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c@@ -402,7 +402,7 @@ void __noreturn die(const char *str, struct pt_regs *regs) } if (regs && kexec_should_crash(current)) - crash_kexec(regs); + crash_kexec_on_oops(regs, current); do_exit(sig); }
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6530f1b..4e1fe20 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c@@ -163,7 +163,7 @@ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, * it through the crashdump code. */ if (kexec_should_crash(current) || (TRAP(regs) == 0x100)) { - crash_kexec(regs); + crash_kexec_on_oops(regs, current); /* * We aren't the primary crash CPU. We need to send it
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 52fbef91d..67c1f8b 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c@@ -1726,7 +1726,7 @@ static void __do_restart(void *ignore) __arch_local_irq_stosm(0x04); /* enable DAT */ smp_send_stop(); #ifdef CONFIG_CRASH_DUMP - crash_kexec(NULL); + crash_kexec(NULL, "restart"); #endif on_restart_trigger.action->fn(&on_restart_trigger); stop_run(&on_restart_trigger);
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index dfdad72..4bfb519 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c@@ -43,7 +43,7 @@ void die(const char *str, struct pt_regs *regs, long err) oops_exit(); if (kexec_should_crash(current)) - crash_kexec(regs); + crash_kexec_on_oops(regs, current); if (in_interrupt()) panic("Fatal exception in interrupt");
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 9c30acf..e973a1d 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c@@ -229,7 +229,7 @@ unsigned long oops_begin(void) void oops_end(unsigned long flags, struct pt_regs *regs, int signr) { if (regs && kexec_should_crash(current)) - crash_kexec(regs); + crash_kexec_on_oops(regs, current); bust_spinlocks(0); die_owner = -1;
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c
index 020c101..8b67644 100644
--- a/arch/x86/platform/uv/uv_nmi.c
+++ b/arch/x86/platform/uv/uv_nmi.c@@ -499,7 +499,7 @@ static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs) /* Call crash to dump system state */ if (master) { pr_emerg("UV: NMI executing crash_kexec on CPU%d\n", cpu); - crash_kexec(regs); + crash_kexec(regs, "UV: NMI executing crash_kexec"); pr_emerg("UV: crash_kexec unexpectedly returned, "); if (!kexec_crash_image) {
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index e804306..0a2744d 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h@@ -237,7 +237,8 @@ extern int kexec_purgatory_get_set_symbol(struct kimage *image, unsigned int size, bool get_value); extern void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name); -extern void crash_kexec(struct pt_regs *); +extern void crash_kexec(struct pt_regs *, char *msg); +extern void crash_kexec_on_oops(struct pt_regs *, struct task_struct *p); int kexec_should_crash(struct task_struct *); void crash_save_cpu(struct pt_regs *regs, int cpu); void crash_save_vmcoreinfo(void);
@@ -321,7 +322,9 @@ int parse_crashkernel_low(char *cmdline, unsigned long long system_ram, #else /* !CONFIG_KEXEC */ struct pt_regs; struct task_struct; -static inline void crash_kexec(struct pt_regs *regs) { } +static inline void crash_kexec(struct pt_regs *regs, char *msg) { } +static inline void crash_kexec_on_oops(struct pt_regs *regs, + struct task_struct *p) { } static inline int kexec_should_crash(struct task_struct *p) { return 0; } #endif /* CONFIG_KEXEC */
diff --git a/kernel/kexec.c b/kernel/kexec.c
index a785c10..9c7894f 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c@@ -1470,7 +1470,7 @@ void __weak crash_unmap_reserved_pages(void) #endif /* CONFIG_KEXEC_FILE */ -void crash_kexec(struct pt_regs *regs) +void crash_kexec(struct pt_regs *regs, char *msg) { /* Take the kexec_mutex here to prevent sys_kexec_load * running on one cpu from replacing the crash kernel
@@ -1493,6 +1493,27 @@ void crash_kexec(struct pt_regs *regs) } } +void crash_kexec_on_oops(struct pt_regs *regs, struct task_struct *p) +{ + static char buf[128]; + char *msg = "Die for unknown reason"; + + if (in_interrupt()) + msg = "Fatal exception in interrupt"; + else if (panic_on_oops) + msg = "Fatal exception"; + else if (!p->pid) + msg = "Attempted to kill the idle task!"; + else if (is_global_init(p)) { + snprintf(buf, sizeof(buf), + "Attempted to kill init! exitcode=0x%08x", + p->signal->group_exit_code ?: p->exit_code); + msg = buf; + } + + crash_kexec(regs, msg); +} + size_t crash_get_memory_size(void) { size_t size = 0;
diff --git a/kernel/panic.c b/kernel/panic.c
index 5252331..93008b6 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c@@ -118,7 +118,7 @@ void panic(const char *fmt, ...) * the "crash_kexec_post_notifiers" option to the kernel. */ if (!crash_kexec_post_notifiers) - crash_kexec(NULL); + crash_kexec(NULL, buf); /* * Note smp_send_stop is the usual smp shutdown function, which
@@ -143,7 +143,7 @@ void panic(const char *fmt, ...) * more unstable, it can increase risks of the kdump failure too. */ if (crash_kexec_post_notifiers) - crash_kexec(NULL); + crash_kexec(NULL, buf); bust_spinlocks(0);