From 4f339ecb30c759f94a29992d4635d9194132b6cf Mon Sep 17 00:00:00 2001 From: Alexander Nyberg Date: Sat, 25 Jun 2005 14:58:27 -0700 Subject: [PATCH] kdump: Save trap information for later analysis If we are faulting in kernel it is quite possible this will lead to a panic. Save trap number, cr2 (in case of page fault) and error_code in the current thread (these fields already exist for signal delivery but are not used here). This helps later kdump crash analyzing from user-space (a script has been submitted to dig this info out in gdb). Signed-off-by: Alexander Nyberg Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/traps.c | 12 ++++++++---- arch/i386/mm/fault.c | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index e458463ebc05..c6077a5ef7ce 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -369,6 +369,10 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e static void do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs * regs, long error_code, siginfo_t *info) { + struct task_struct *tsk = current; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + if (regs->eflags & VM_MASK) { if (vm86) goto vm86_trap; @@ -379,9 +383,6 @@ static void do_trap(int trapnr, int signr, char *str, int vm86, goto kernel_trap; trap_signal: { - struct task_struct *tsk = current; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; if (info) force_sig_info(signr, info, tsk); else @@ -494,6 +495,9 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code) } put_cpu(); + current->thread.error_code = error_code; + current->thread.trap_no = 13; + if (regs->eflags & VM_MASK) goto gp_in_vm86; @@ -897,9 +901,9 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs, error_code); return; } - die_if_kernel("cache flush denied", regs, error_code); current->thread.trap_no = 19; current->thread.error_code = error_code; + die_if_kernel("cache flush denied", regs, error_code); force_sig(SIGSEGV, current); } } diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index a509237c4815..92ed6c0a55da 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -463,6 +463,9 @@ no_context: printk(KERN_ALERT "*pte = %08lx\n", page); } #endif + tsk->thread.cr2 = address; + tsk->thread.trap_no = 14; + tsk->thread.error_code = error_code; die("Oops", regs, error_code); bust_spinlocks(0); do_exit(SIGKILL); -- cgit v1.2.2