[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:
parent
6e274d1443
commit
4f339ecb30
2 changed files with 11 additions and 4 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue