Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a604b380 authored by Harvey Harrison's avatar Harvey Harrison Committed by Ingo Molnar
Browse files

x86: introduce __die helper to X86_32



Small step towards unifying traps_32|64.c.  No functional
changes.  Pull out a small helper from an if() statement
in die().

Marked as __kprobes as eventually we will want to call this
from do_page_fault similar to how X86_64 does it.

Signed-off-by: default avatarHarvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent c68461b6
Loading
Loading
Loading
Loading
+42 −34
Original line number Diff line number Diff line
@@ -352,6 +352,45 @@ int is_valid_bugaddr(unsigned long ip)
	return ud2 == 0x0b0f;
}

static int die_counter;

int __kprobes __die(const char * str, struct pt_regs * regs, long err)
{
	unsigned long sp;
	unsigned short ss;

	printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
#ifdef CONFIG_PREEMPT
	printk("PREEMPT ");
#endif
#ifdef CONFIG_SMP
	printk("SMP ");
#endif
#ifdef CONFIG_DEBUG_PAGEALLOC
	printk("DEBUG_PAGEALLOC");
#endif
	printk("\n");

	if (notify_die(DIE_OOPS, str, regs, err,
				current->thread.trap_no, SIGSEGV) !=
			NOTIFY_STOP) {
		show_registers(regs);
		/* Executive summary in case the oops scrolled away */
		sp = (unsigned long) (&regs->sp);
		savesegment(ss, ss);
		if (user_mode(regs)) {
			sp = regs->sp;
			ss = regs->ss & 0xffff;
		}
		printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
		print_symbol("%s", regs->ip);
		printk(" SS:ESP %04x:%08lx\n", ss, sp);
		return 0;
	} else {
		return 1;
	}
}

/*
 * This is gone through when something in the kernel has done something bad and
 * is about to be terminated.
@@ -367,7 +406,6 @@ void die(const char * str, struct pt_regs * regs, long err)
		.lock_owner =		-1,
		.lock_owner_depth =	0
	};
	static int die_counter;
	unsigned long flags;

	oops_enter();
@@ -383,43 +421,13 @@ void die(const char * str, struct pt_regs * regs, long err)
		raw_local_irq_save(flags);

	if (++die.lock_owner_depth < 3) {
		unsigned long sp;
		unsigned short ss;

		report_bug(regs->ip, regs);

		printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,
		       ++die_counter);
#ifdef CONFIG_PREEMPT
		printk("PREEMPT ");
#endif
#ifdef CONFIG_SMP
		printk("SMP ");
#endif
#ifdef CONFIG_DEBUG_PAGEALLOC
		printk("DEBUG_PAGEALLOC");
#endif
		printk("\n");

		if (notify_die(DIE_OOPS, str, regs, err,
					current->thread.trap_no, SIGSEGV) !=
				NOTIFY_STOP) {
			show_registers(regs);
			/* Executive summary in case the oops scrolled away */
			sp = (unsigned long) (&regs->sp);
			savesegment(ss, ss);
			if (user_mode(regs)) {
				sp = regs->sp;
				ss = regs->ss & 0xffff;
			}
			printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
			print_symbol("%s", regs->ip);
			printk(" SS:ESP %04x:%08lx\n", ss, sp);
		}
		else
		if (__die(str, regs, err))
			regs = NULL;
  	} else
	} else {
		printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
	}

	bust_spinlocks(0);
	die.lock_owner = -1;