From: Alexander Nyberg Date: Sat, 25 Jun 2005 21:58:27 +0000 (-0700) Subject: [PATCH] kdump: Save trap information for later analysis X-Git-Tag: v2.6.13-rc1~68^2~87 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f339ecb30c759f94a29992d4635d9194132b6cf;p=linux-2.6 [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 --- diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index e458463ebc..c6077a5ef7 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 a509237c48..92ed6c0a55 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);