aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/traps.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 2cd429117a41..ab8dad719b9e 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -171,41 +171,37 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
171 force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk); 171 force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk);
172} 172}
173 173
174static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
175 unsigned long trapnr, int signr, siginfo_t *info)
176{
177 enum ctx_state prev_state = exception_enter();
178
179 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
180 NOTIFY_STOP) {
181 conditional_sti(regs);
182 do_trap(trapnr, signr, str, regs, error_code, info);
183 }
184
185 exception_exit(prev_state);
186}
187
174#define DO_ERROR(trapnr, signr, str, name) \ 188#define DO_ERROR(trapnr, signr, str, name) \
175dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ 189dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
176{ \ 190{ \
177 enum ctx_state prev_state; \ 191 do_error_trap(regs, error_code, str, trapnr, signr, NULL); \
178 \
179 prev_state = exception_enter(); \
180 if (notify_die(DIE_TRAP, str, regs, error_code, \
181 trapnr, signr) == NOTIFY_STOP) { \
182 exception_exit(prev_state); \
183 return; \
184 } \
185 conditional_sti(regs); \
186 do_trap(trapnr, signr, str, regs, error_code, NULL); \
187 exception_exit(prev_state); \
188} 192}
189 193
190#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ 194#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
191dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ 195dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
192{ \ 196{ \
193 siginfo_t info; \ 197 siginfo_t info; \
194 enum ctx_state prev_state; \
195 \ 198 \
196 info.si_signo = signr; \ 199 info.si_signo = signr; \
197 info.si_errno = 0; \ 200 info.si_errno = 0; \
198 info.si_code = sicode; \ 201 info.si_code = sicode; \
199 info.si_addr = (void __user *)siaddr; \ 202 info.si_addr = (void __user *)siaddr; \
200 prev_state = exception_enter(); \ 203 \
201 if (notify_die(DIE_TRAP, str, regs, error_code, \ 204 do_error_trap(regs, error_code, str, trapnr, signr, &info); \
202 trapnr, signr) == NOTIFY_STOP) { \
203 exception_exit(prev_state); \
204 return; \
205 } \
206 conditional_sti(regs); \
207 do_trap(trapnr, signr, str, regs, error_code, &info); \
208 exception_exit(prev_state); \
209} 205}
210 206
211DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip ) 207DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip )