forked from luck/tmp_suning_uos_patched
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:
parent
b4b8f87bf4
commit
874d93d118
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user