2005-05-18 12:42:18

by Vivek Goyal

[permalink] [raw]
Subject: Re: [Fastboot] [2/2] kdump: Save trap information for later analyzis

On Sat, May 14, 2005 at 10:50:00PM +0200, Alexander Nyberg wrote:
> 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 <[email protected]>
>
> Index: mm/arch/i386/mm/fault.c
> ===================================================================
> --- mm.orig/arch/i386/mm/fault.c 2005-05-14 22:05:56.000000000 +0200
> +++ mm/arch/i386/mm/fault.c 2005-05-14 22:06:21.000000000 +0200
> @@ -469,6 +469,9 @@
> 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);
> Index: mm/arch/i386/kernel/traps.c
> ===================================================================
> --- mm.orig/arch/i386/kernel/traps.c 2005-05-14 22:05:56.000000000 +0200
> +++ mm/arch/i386/kernel/traps.c 2005-05-14 22:06:21.000000000 +0200
> @@ -431,8 +431,11 @@
> }
>
> kernel_trap: {
> - if (!fixup_exception(regs))
> + if (!fixup_exception(regs)) {
> + current->thread.trap_no = trapnr;
> + current->thread.error_code = error_code;
> die(str, regs, error_code);
> + }
> return;
> }
>
> @@ -537,6 +540,9 @@
> }
> put_cpu();
>
> + current->thread.error_code = error_code;
> + current->thread.trap_no = 13;
> +


This assignment is being done again in case thread was running in user mode.
That can now be done away with as above code will take care of both the cases.

if (!user_mode(regs))
goto gp_in_kernel;

current->thread.error_code = error_code;
current->thread.trap_no = 13;
force_sig(SIGSEGV, current);



> if (regs->eflags & VM_MASK)
> goto gp_in_vm86;
>
> @@ -977,9 +983,9 @@
> 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);
> }
> }
>
>

> _______________________________________________
> fastboot mailing list
> [email protected]
> http://lists.osdl.org/mailman/listinfo/fastboot


2005-05-18 14:52:32

by Alexander Nyberg

[permalink] [raw]
Subject: Re: [Fastboot] [2/2] kdump: Save trap information for later analyzis

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 <[email protected]>

Index: mm/arch/i386/mm/fault.c
===================================================================
--- mm.orig/arch/i386/mm/fault.c 2005-05-18 16:39:04.000000000 +0200
+++ mm/arch/i386/mm/fault.c 2005-05-18 16:39:20.000000000 +0200
@@ -469,6 +469,9 @@
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);
Index: mm/arch/i386/kernel/traps.c
===================================================================
--- mm.orig/arch/i386/kernel/traps.c 2005-05-18 16:39:04.000000000 +0200
+++ mm/arch/i386/kernel/traps.c 2005-05-18 16:39:20.000000000 +0200
@@ -410,6 +410,10 @@
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;
@@ -420,9 +424,6 @@
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
@@ -537,6 +538,9 @@
}
put_cpu();

+ current->thread.error_code = error_code;
+ current->thread.trap_no = 13;
+
if (regs->eflags & VM_MASK)
goto gp_in_vm86;

@@ -977,9 +981,9 @@
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);
}
}