diff options
-rw-r--r-- | arch/x86/kernel/traps.c | 38 |
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 | ||
174 | static 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) \ |
175 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 189 | dotraplinkage 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) \ |
191 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 195 | dotraplinkage 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 | ||
211 | DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip ) | 207 | DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip ) |