[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>

authored by

Alexander Nyberg and committed by
Linus Torvalds
4f339ecb 6e274d14

+11 -4
+8 -4
arch/i386/kernel/traps.c
··· 369 369 static void do_trap(int trapnr, int signr, char *str, int vm86, 370 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 376 if (regs->eflags & VM_MASK) { 373 377 if (vm86) 374 378 goto vm86_trap; ··· 383 379 goto kernel_trap; 384 380 385 381 trap_signal: { 386 - struct task_struct *tsk = current; 387 - tsk->thread.error_code = error_code; 388 - tsk->thread.trap_no = trapnr; 389 382 if (info) 390 383 force_sig_info(signr, info, tsk); 391 384 else ··· 494 493 return; 495 494 } 496 495 put_cpu(); 496 + 497 + current->thread.error_code = error_code; 498 + current->thread.trap_no = 13; 497 499 498 500 if (regs->eflags & VM_MASK) 499 501 goto gp_in_vm86; ··· 901 897 error_code); 902 898 return; 903 899 } 904 - die_if_kernel("cache flush denied", regs, error_code); 905 900 current->thread.trap_no = 19; 906 901 current->thread.error_code = error_code; 902 + die_if_kernel("cache flush denied", regs, error_code); 907 903 force_sig(SIGSEGV, current); 908 904 } 909 905 }
+3
arch/i386/mm/fault.c
··· 463 463 printk(KERN_ALERT "*pte = %08lx\n", page); 464 464 } 465 465 #endif 466 + tsk->thread.cr2 = address; 467 + tsk->thread.trap_no = 14; 468 + tsk->thread.error_code = error_code; 466 469 die("Oops", regs, error_code); 467 470 bust_spinlocks(0); 468 471 do_exit(SIGKILL);