Commit dff0796e authored by Oleg Nesterov's avatar Oleg Nesterov
Browse files

x86/traps: Introduce do_error_trap()



Move the common code from DO_ERROR() and DO_ERROR_INFO() into the new
helper, do_error_trap(). This simplifies define's and shaves 527 bytes
from traps.o.

Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
parent 38cad57b
Loading
Loading
Loading
Loading
+17 −21
Original line number Diff line number Diff line
@@ -171,41 +171,37 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
	force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk);
}

static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
			  unsigned long trapnr, int signr, siginfo_t *info)
{
	enum ctx_state prev_state = exception_enter();

	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
			NOTIFY_STOP) {
		conditional_sti(regs);
		do_trap(trapnr, signr, str, regs, error_code, info);
	}

	exception_exit(prev_state);
}

#define DO_ERROR(trapnr, signr, str, name)				\
dotraplinkage void do_##name(struct pt_regs *regs, long error_code)	\
{									\
	enum ctx_state prev_state;					\
									\
	prev_state = exception_enter();					\
	if (notify_die(DIE_TRAP, str, regs, error_code,			\
			trapnr, signr) == NOTIFY_STOP) {		\
		exception_exit(prev_state);				\
		return;							\
	}								\
	conditional_sti(regs);						\
	do_trap(trapnr, signr, str, regs, error_code, NULL);		\
	exception_exit(prev_state);					\
	do_error_trap(regs, error_code, str, trapnr, signr, NULL);	\
}

#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr)		\
dotraplinkage void do_##name(struct pt_regs *regs, long error_code)	\
{									\
	siginfo_t info;							\
	enum ctx_state prev_state;					\
									\
	info.si_signo = signr;						\
	info.si_errno = 0;						\
	info.si_code = sicode;						\
	info.si_addr = (void __user *)siaddr;				\
	prev_state = exception_enter();					\
	if (notify_die(DIE_TRAP, str, regs, error_code,			\
			trapnr, signr) == NOTIFY_STOP) {		\
		exception_exit(prev_state);				\
		return;							\
	}								\
	conditional_sti(regs);						\
	do_trap(trapnr, signr, str, regs, error_code, &info);		\
	exception_exit(prev_state);					\
									\
	do_error_trap(regs, error_code, str, trapnr, signr, &info);	\
}

DO_ERROR_INFO(X86_TRAP_DE,     SIGFPE,  "divide error",			divide_error,		     FPE_INTDIV, regs->ip )