diff options
author | Alexander Nyberg <alexn@telia.com> | 2005-06-25 17:58:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-25 19:24:55 -0400 |
commit | 4f339ecb30c759f94a29992d4635d9194132b6cf (patch) | |
tree | 9a1438b35d87a1d3a3359c273a39ac4895578e1c /arch | |
parent | 6e274d144302068a00794ec22e73520c0615cb6f (diff) |
[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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/traps.c | 12 | ||||
-rw-r--r-- | 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 | |||
369 | static void do_trap(int trapnr, int signr, char *str, int vm86, | 369 | static void do_trap(int trapnr, int signr, char *str, int vm86, |
370 | struct pt_regs * regs, long error_code, siginfo_t *info) | 370 | struct pt_regs * regs, long error_code, siginfo_t *info) |
371 | { | 371 | { |
372 | struct task_struct *tsk = current; | ||
373 | tsk->thread.error_code = error_code; | ||
374 | tsk->thread.trap_no = trapnr; | ||
375 | |||
372 | if (regs->eflags & VM_MASK) { | 376 | if (regs->eflags & VM_MASK) { |
373 | if (vm86) | 377 | if (vm86) |
374 | goto vm86_trap; | 378 | goto vm86_trap; |
@@ -379,9 +383,6 @@ static void do_trap(int trapnr, int signr, char *str, int vm86, | |||
379 | goto kernel_trap; | 383 | goto kernel_trap; |
380 | 384 | ||
381 | trap_signal: { | 385 | trap_signal: { |
382 | struct task_struct *tsk = current; | ||
383 | tsk->thread.error_code = error_code; | ||
384 | tsk->thread.trap_no = trapnr; | ||
385 | if (info) | 386 | if (info) |
386 | force_sig_info(signr, info, tsk); | 387 | force_sig_info(signr, info, tsk); |
387 | else | 388 | else |
@@ -494,6 +495,9 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code) | |||
494 | } | 495 | } |
495 | put_cpu(); | 496 | put_cpu(); |
496 | 497 | ||
498 | current->thread.error_code = error_code; | ||
499 | current->thread.trap_no = 13; | ||
500 | |||
497 | if (regs->eflags & VM_MASK) | 501 | if (regs->eflags & VM_MASK) |
498 | goto gp_in_vm86; | 502 | goto gp_in_vm86; |
499 | 503 | ||
@@ -897,9 +901,9 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs, | |||
897 | error_code); | 901 | error_code); |
898 | return; | 902 | return; |
899 | } | 903 | } |
900 | die_if_kernel("cache flush denied", regs, error_code); | ||
901 | current->thread.trap_no = 19; | 904 | current->thread.trap_no = 19; |
902 | current->thread.error_code = error_code; | 905 | current->thread.error_code = error_code; |
906 | die_if_kernel("cache flush denied", regs, error_code); | ||
903 | force_sig(SIGSEGV, current); | 907 | force_sig(SIGSEGV, current); |
904 | } | 908 | } |
905 | } | 909 | } |
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: | |||
463 | printk(KERN_ALERT "*pte = %08lx\n", page); | 463 | printk(KERN_ALERT "*pte = %08lx\n", page); |
464 | } | 464 | } |
465 | #endif | 465 | #endif |
466 | tsk->thread.cr2 = address; | ||
467 | tsk->thread.trap_no = 14; | ||
468 | tsk->thread.error_code = error_code; | ||
466 | die("Oops", regs, error_code); | 469 | die("Oops", regs, error_code); |
467 | bust_spinlocks(0); | 470 | bust_spinlocks(0); |
468 | do_exit(SIGKILL); | 471 | do_exit(SIGKILL); |