[PATCH] x86, dumpstack: make die and die_nmi equal
Alexander van Heukelum
heukelum at mailshack.com
Mon Oct 20 11:11:06 EDT 2008
Use the x86_64 version of die() and die_nmi() on i386 too.
Changes to the original x86_64-version have no influence
on the generated code:
- whitespace, comments
- use user_mode_vm() instead of user_mode()
Signed-off-by: Alexander van Heukelum <heukelum at fastmail.fm>
---
arch/x86/kernel/dumpstack_32.c | 40 ++++++++++++++--------------------------
arch/x86/kernel/dumpstack_64.c | 9 +++++++--
2 files changed, 21 insertions(+), 28 deletions(-)
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index e45952b..6f00938 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -377,52 +377,40 @@ void die(const char *str, struct pt_regs *regs, long err)
{
unsigned long flags = oops_begin();
- if (die_nest_count < 3) {
+ if (!user_mode_vm(regs))
report_bug(regs->ip, regs);
- if (__die(str, regs, err))
- regs = NULL;
- } else {
- printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
- }
+ if (__die(str, regs, err))
+ regs = NULL;
oops_end(flags, regs, SIGSEGV);
}
-static DEFINE_SPINLOCK(nmi_print_lock);
-
void notrace __kprobes
die_nmi(char *str, struct pt_regs *regs, int do_panic)
{
+ unsigned long flags;
+
if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP)
return;
- spin_lock(&nmi_print_lock);
+ flags = oops_begin();
/*
* We are in trouble anyway, lets at least try
- * to get a message out:
+ * to get a message out.
*/
- bust_spinlocks(1);
printk(KERN_EMERG "%s", str);
printk(" on CPU%d, ip %08lx, registers:\n",
smp_processor_id(), regs->ip);
show_registers(regs);
- if (do_panic)
- panic("Non maskable interrupt");
- console_silent();
- spin_unlock(&nmi_print_lock);
- bust_spinlocks(0);
-
- /*
- * If we are in kernel we are probably nested up pretty bad
- * and might aswell get out now while we still can:
- */
- if (!user_mode_vm(regs)) {
- current->thread.trap_no = 2;
+ if (kexec_should_crash(current))
crash_kexec(regs);
- }
-
- do_exit(SIGSEGV);
+ if (do_panic || panic_on_oops)
+ panic("Non maskable interrupt");
+ oops_end(flags, NULL, SIGBUS);
+ nmi_exit();
+ local_irq_enable();
+ do_exit(SIGBUS);
}
static int __init oops_setup(char *s)
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index cd7b46b..dbcca05 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -508,19 +508,24 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
return 0;
}
+/*
+ * This is gone through when something in the kernel has done something bad
+ * and is about to be terminated:
+ */
void die(const char *str, struct pt_regs *regs, long err)
{
unsigned long flags = oops_begin();
- if (!user_mode(regs))
+ if (!user_mode_vm(regs))
report_bug(regs->ip, regs);
if (__die(str, regs, err))
regs = NULL;
+
oops_end(flags, regs, SIGSEGV);
}
-notrace __kprobes void
+void notrace __kprobes
die_nmi(char *str, struct pt_regs *regs, int do_panic)
{
unsigned long flags;
--
1.5.4.3
More information about the kexec
mailing list