[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 <alexn@telia.com>
Cc: <fastboot@lists.osdl.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Alexander Nyberg 2005-06-25 14:58:27 -07:00 committed by Linus Torvalds
parent 6e274d1443
commit 4f339ecb30
2 changed files with 11 additions and 4 deletions

View file

@ -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, static void do_trap(int trapnr, int signr, char *str, int vm86,
struct pt_regs * regs, long error_code, siginfo_t *info) 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 (regs->eflags & VM_MASK) {
if (vm86) if (vm86)
goto vm86_trap; goto vm86_trap;
@ -379,9 +383,6 @@ static void do_trap(int trapnr, int signr, char *str, int vm86,
goto kernel_trap; goto kernel_trap;
trap_signal: { trap_signal: {
struct task_struct *tsk = current;
tsk->thread.error_code = error_code;
tsk->thread.trap_no = trapnr;
if (info) if (info)
force_sig_info(signr, info, tsk); force_sig_info(signr, info, tsk);
else else
@ -494,6 +495,9 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
} }
put_cpu(); put_cpu();
current->thread.error_code = error_code;
current->thread.trap_no = 13;
if (regs->eflags & VM_MASK) if (regs->eflags & VM_MASK)
goto gp_in_vm86; goto gp_in_vm86;
@ -897,9 +901,9 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
error_code); error_code);
return; return;
} }
die_if_kernel("cache flush denied", regs, error_code);
current->thread.trap_no = 19; current->thread.trap_no = 19;
current->thread.error_code = error_code; current->thread.error_code = error_code;
die_if_kernel("cache flush denied", regs, error_code);
force_sig(SIGSEGV, current); force_sig(SIGSEGV, current);
} }
} }

View file

@ -463,6 +463,9 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
printk(KERN_ALERT "*pte = %08lx\n", page); printk(KERN_ALERT "*pte = %08lx\n", page);
} }
#endif #endif
tsk->thread.cr2 = address;
tsk->thread.trap_no = 14;
tsk->thread.error_code = error_code;
die("Oops", regs, error_code); die("Oops", regs, error_code);
bust_spinlocks(0); bust_spinlocks(0);
do_exit(SIGKILL); do_exit(SIGKILL);