x86, dumpstack: let signr=0 signal no do_exit

Change oops_end such that signr=0 signals that do_exit
is not to be called.

Currently, each use of __die is soon followed by a call
to oops_end and 'regs' is set to NULL if oops_end is expected
not to call do_exit. Change all such pairs to set signr=0
instead. On x86_64 oops_end is used 'bare' in die_nmi; use
signr=0 instead of regs=NULL there, too.

Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Alexander van Heukelum 2008-10-22 12:00:09 +02:00 committed by Ingo Molnar
parent b4b8f87bf4
commit 874d93d118
3 changed files with 16 additions and 11 deletions

View File

@ -318,7 +318,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
__raw_spin_unlock(&die_lock); __raw_spin_unlock(&die_lock);
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
if (!regs) if (!signr)
return; return;
if (in_interrupt()) if (in_interrupt())
@ -371,17 +371,18 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
void die(const char *str, struct pt_regs *regs, long err) void die(const char *str, struct pt_regs *regs, long err)
{ {
unsigned long flags = oops_begin(); unsigned long flags = oops_begin();
int sig = SIGSEGV;
if (die_nest_count < 3) { if (die_nest_count < 3) {
report_bug(regs->ip, regs); report_bug(regs->ip, regs);
if (__die(str, regs, err)) if (__die(str, regs, err))
regs = NULL; sig = 0;
} else { } else {
printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
} }
oops_end(flags, regs, SIGSEGV); oops_end(flags, regs, sig);
} }
static DEFINE_SPINLOCK(nmi_print_lock); static DEFINE_SPINLOCK(nmi_print_lock);

View File

@ -465,7 +465,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
/* Nest count reaches zero, release the lock. */ /* Nest count reaches zero, release the lock. */
__raw_spin_unlock(&die_lock); __raw_spin_unlock(&die_lock);
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
if (!regs) { if (!signr) {
oops_exit(); oops_exit();
return; return;
} }
@ -509,13 +509,14 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
void die(const char *str, struct pt_regs *regs, long err) void die(const char *str, struct pt_regs *regs, long err)
{ {
unsigned long flags = oops_begin(); unsigned long flags = oops_begin();
int sig = SIGSEGV;
if (!user_mode(regs)) if (!user_mode(regs))
report_bug(regs->ip, regs); report_bug(regs->ip, regs);
if (__die(str, regs, err)) if (__die(str, regs, err))
regs = NULL; sig = 0;
oops_end(flags, regs, SIGSEGV); oops_end(flags, regs, sig);
} }
notrace __kprobes void notrace __kprobes void
@ -539,7 +540,7 @@ die_nmi(char *str, struct pt_regs *regs, int do_panic)
crash_kexec(regs); crash_kexec(regs);
if (do_panic || panic_on_oops) if (do_panic || panic_on_oops)
panic("Non maskable interrupt"); panic("Non maskable interrupt");
oops_end(flags, NULL, SIGBUS); oops_end(flags, regs, 0);
nmi_exit(); nmi_exit();
local_irq_enable(); local_irq_enable();
do_exit(SIGBUS); do_exit(SIGBUS);

View File

@ -413,6 +413,7 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
unsigned long error_code) unsigned long error_code)
{ {
unsigned long flags = oops_begin(); unsigned long flags = oops_begin();
int sig = SIGKILL;
struct task_struct *tsk; struct task_struct *tsk;
printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
@ -423,8 +424,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
tsk->thread.trap_no = 14; tsk->thread.trap_no = 14;
tsk->thread.error_code = error_code; tsk->thread.error_code = error_code;
if (__die("Bad pagetable", regs, error_code)) if (__die("Bad pagetable", regs, error_code))
regs = NULL; sig = 0;
oops_end(flags, regs, SIGKILL); oops_end(flags, regs, sig);
} }
#endif #endif
@ -590,6 +591,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
int fault; int fault;
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
unsigned long flags; unsigned long flags;
int sig;
#endif #endif
tsk = current; tsk = current;
@ -849,11 +851,12 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
bust_spinlocks(0); bust_spinlocks(0);
do_exit(SIGKILL); do_exit(SIGKILL);
#else #else
sig = SIGKILL;
if (__die("Oops", regs, error_code)) if (__die("Oops", regs, error_code))
regs = NULL; sig = 0;
/* Executive summary in case the body of the oops scrolled away */ /* Executive summary in case the body of the oops scrolled away */
printk(KERN_EMERG "CR2: %016lx\n", address); printk(KERN_EMERG "CR2: %016lx\n", address);
oops_end(flags, regs, SIGKILL); oops_end(flags, regs, sig);
#endif #endif
/* /*