Commit 874d93d1 authored by Alexander van Heukelum's avatar Alexander van Heukelum Committed by Ingo Molnar
Browse files

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: default avatarAlexander van Heukelum <heukelum@fastmail.fm>
Acked-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent b4b8f87b
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -318,7 +318,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
	__raw_spin_unlock(&die_lock);
	raw_local_irq_restore(flags);

	if (!regs)
	if (!signr)
		return;

	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)
{
	unsigned long flags = oops_begin();
	int sig = SIGSEGV;

	if (die_nest_count < 3) {
		report_bug(regs->ip, regs);

		if (__die(str, regs, err))
			regs = NULL;
			sig = 0;
	} else {
		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);
+5 −4
Original line number Diff line number Diff line
@@ -465,7 +465,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
		/* Nest count reaches zero, release the lock. */
		__raw_spin_unlock(&die_lock);
	raw_local_irq_restore(flags);
	if (!regs) {
	if (!signr) {
		oops_exit();
		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)
{
	unsigned long flags = oops_begin();
	int sig = SIGSEGV;

	if (!user_mode(regs))
		report_bug(regs->ip, regs);

	if (__die(str, regs, err))
		regs = NULL;
	oops_end(flags, regs, SIGSEGV);
		sig = 0;
	oops_end(flags, regs, sig);
}

notrace __kprobes void
@@ -539,7 +540,7 @@ die_nmi(char *str, struct pt_regs *regs, int do_panic)
		crash_kexec(regs);
	if (do_panic || panic_on_oops)
		panic("Non maskable interrupt");
	oops_end(flags, NULL, SIGBUS);
	oops_end(flags, regs, 0);
	nmi_exit();
	local_irq_enable();
	do_exit(SIGBUS);
+7 −4
Original line number Diff line number Diff line
@@ -413,6 +413,7 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
				 unsigned long error_code)
{
	unsigned long flags = oops_begin();
	int sig = SIGKILL;
	struct task_struct *tsk;

	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.error_code = error_code;
	if (__die("Bad pagetable", regs, error_code))
		regs = NULL;
	oops_end(flags, regs, SIGKILL);
		sig = 0;
	oops_end(flags, regs, sig);
}
#endif

@@ -590,6 +591,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
	int fault;
#ifdef CONFIG_X86_64
	unsigned long flags;
	int sig;
#endif

	tsk = current;
@@ -849,11 +851,12 @@ no_context:
	bust_spinlocks(0);
	do_exit(SIGKILL);
#else
	sig = SIGKILL;
	if (__die("Oops", regs, error_code))
		regs = NULL;
		sig = 0;
	/* Executive summary in case the body of the oops scrolled away */
	printk(KERN_EMERG "CR2: %016lx\n", address);
	oops_end(flags, regs, SIGKILL);
	oops_end(flags, regs, sig);
#endif

/*