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