Commit 4f339ecb authored by Alexander Nyberg's avatar Alexander Nyberg Committed by Linus Torvalds
Browse files

[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: default avatarAlexander Nyberg <alexn@telia.com>
Cc: <fastboot@lists.osdl.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 6e274d14
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -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);
	}
}
+3 −0
Original line number Diff line number Diff line
@@ -463,6 +463,9 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
		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);