|
@@ -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 )
|