diff options
| -rw-r--r-- | arch/x86/kernel/traps.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 1cf8a4c409b6..c9dd74124038 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -136,13 +136,16 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, | |||
| 136 | return -1; | 136 | return -1; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | static void fill_trap_info(struct pt_regs *regs, int signr, int trapnr, | 139 | static siginfo_t *fill_trap_info(struct pt_regs *regs, int signr, int trapnr, |
| 140 | siginfo_t *info) | 140 | siginfo_t *info) |
| 141 | { | 141 | { |
| 142 | unsigned long siaddr; | 142 | unsigned long siaddr; |
| 143 | int sicode; | 143 | int sicode; |
| 144 | 144 | ||
| 145 | switch (trapnr) { | 145 | switch (trapnr) { |
| 146 | default: | ||
| 147 | return SEND_SIG_PRIV; | ||
| 148 | |||
| 146 | case X86_TRAP_DE: | 149 | case X86_TRAP_DE: |
| 147 | sicode = FPE_INTDIV; | 150 | sicode = FPE_INTDIV; |
| 148 | siaddr = regs->ip; | 151 | siaddr = regs->ip; |
| @@ -161,6 +164,7 @@ static void fill_trap_info(struct pt_regs *regs, int signr, int trapnr, | |||
| 161 | info->si_errno = 0; | 164 | info->si_errno = 0; |
| 162 | info->si_code = sicode; | 165 | info->si_code = sicode; |
| 163 | info->si_addr = (void __user *)siaddr; | 166 | info->si_addr = (void __user *)siaddr; |
| 167 | return info; | ||
| 164 | } | 168 | } |
| 165 | 169 | ||
| 166 | static void __kprobes | 170 | static void __kprobes |
| @@ -199,14 +203,16 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | |||
| 199 | } | 203 | } |
| 200 | 204 | ||
| 201 | static void do_error_trap(struct pt_regs *regs, long error_code, char *str, | 205 | static void do_error_trap(struct pt_regs *regs, long error_code, char *str, |
| 202 | unsigned long trapnr, int signr, siginfo_t *info) | 206 | unsigned long trapnr, int signr) |
| 203 | { | 207 | { |
| 204 | enum ctx_state prev_state = exception_enter(); | 208 | enum ctx_state prev_state = exception_enter(); |
| 209 | siginfo_t info; | ||
| 205 | 210 | ||
| 206 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != | 211 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != |
| 207 | NOTIFY_STOP) { | 212 | NOTIFY_STOP) { |
| 208 | conditional_sti(regs); | 213 | conditional_sti(regs); |
| 209 | do_trap(trapnr, signr, str, regs, error_code, info); | 214 | do_trap(trapnr, signr, str, regs, error_code, |
| 215 | fill_trap_info(regs, signr, trapnr, &info)); | ||
| 210 | } | 216 | } |
| 211 | 217 | ||
| 212 | exception_exit(prev_state); | 218 | exception_exit(prev_state); |
| @@ -215,16 +221,13 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str, | |||
| 215 | #define DO_ERROR(trapnr, signr, str, name) \ | 221 | #define DO_ERROR(trapnr, signr, str, name) \ |
| 216 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 222 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ |
| 217 | { \ | 223 | { \ |
| 218 | do_error_trap(regs, error_code, str, trapnr, signr, NULL); \ | 224 | do_error_trap(regs, error_code, str, trapnr, signr); \ |
| 219 | } | 225 | } |
| 220 | 226 | ||
| 221 | #define DO_ERROR_INFO(trapnr, signr, str, name) \ | 227 | #define DO_ERROR_INFO(trapnr, signr, str, name) \ |
| 222 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 228 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ |
| 223 | { \ | 229 | { \ |
| 224 | siginfo_t info; \ | 230 | do_error_trap(regs, error_code, str, trapnr, signr); \ |
| 225 | \ | ||
| 226 | fill_trap_info(regs, signr, trapnr, &info); \ | ||
| 227 | do_error_trap(regs, error_code, str, trapnr, signr, &info); \ | ||
| 228 | } | 231 | } |
| 229 | 232 | ||
| 230 | DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error) | 233 | DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error) |
