diff options
Diffstat (limited to 'arch/x86/kernel/traps.c')
| -rw-r--r-- | arch/x86/kernel/traps.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 378967578f22..cfbe3fc41586 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -108,30 +108,45 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) | |||
| 108 | dec_preempt_count(); | 108 | dec_preempt_count(); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static void __kprobes | 111 | static int __kprobes |
| 112 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | 112 | do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, |
| 113 | long error_code, siginfo_t *info) | 113 | struct pt_regs *regs, long error_code) |
| 114 | { | 114 | { |
| 115 | struct task_struct *tsk = current; | ||
| 116 | |||
| 117 | #ifdef CONFIG_X86_32 | 115 | #ifdef CONFIG_X86_32 |
| 118 | if (regs->flags & X86_VM_MASK) { | 116 | if (regs->flags & X86_VM_MASK) { |
| 119 | /* | 117 | /* |
| 120 | * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. | 118 | * Traps 0, 1, 3, 4, and 5 should be forwarded to vm86. |
| 121 | * On nmi (interrupt 2), do_trap should not be called. | 119 | * On nmi (interrupt 2), do_trap should not be called. |
| 122 | */ | 120 | */ |
| 123 | if (trapnr < X86_TRAP_UD) | 121 | if (trapnr < X86_TRAP_UD) { |
| 124 | goto vm86_trap; | 122 | if (!handle_vm86_trap((struct kernel_vm86_regs *) regs, |
| 125 | goto trap_signal; | 123 | error_code, trapnr)) |
| 124 | return 0; | ||
| 125 | } | ||
| 126 | return -1; | ||
| 126 | } | 127 | } |
| 127 | #endif | 128 | #endif |
| 129 | if (!user_mode(regs)) { | ||
| 130 | if (!fixup_exception(regs)) { | ||
| 131 | tsk->thread.error_code = error_code; | ||
| 132 | tsk->thread.trap_nr = trapnr; | ||
| 133 | die(str, regs, error_code); | ||
| 134 | } | ||
| 135 | return 0; | ||
| 136 | } | ||
| 128 | 137 | ||
| 129 | if (!user_mode(regs)) | 138 | return -1; |
| 130 | goto kernel_trap; | 139 | } |
| 131 | 140 | ||
| 132 | #ifdef CONFIG_X86_32 | 141 | static void __kprobes |
| 133 | trap_signal: | 142 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, |
| 134 | #endif | 143 | long error_code, siginfo_t *info) |
| 144 | { | ||
| 145 | struct task_struct *tsk = current; | ||
| 146 | |||
| 147 | |||
| 148 | if (!do_trap_no_signal(tsk, trapnr, str, regs, error_code)) | ||
| 149 | return; | ||
| 135 | /* | 150 | /* |
| 136 | * We want error_code and trap_nr set for userspace faults and | 151 | * We want error_code and trap_nr set for userspace faults and |
| 137 | * kernelspace faults which result in die(), but not | 152 | * kernelspace faults which result in die(), but not |
| @@ -159,23 +174,6 @@ trap_signal: | |||
| 159 | force_sig_info(signr, info, tsk); | 174 | force_sig_info(signr, info, tsk); |
| 160 | else | 175 | else |
| 161 | force_sig(signr, tsk); | 176 | force_sig(signr, tsk); |
| 162 | return; | ||
| 163 | |||
| 164 | kernel_trap: | ||
| 165 | if (!fixup_exception(regs)) { | ||
| 166 | tsk->thread.error_code = error_code; | ||
| 167 | tsk->thread.trap_nr = trapnr; | ||
| 168 | die(str, regs, error_code); | ||
| 169 | } | ||
| 170 | return; | ||
| 171 | |||
| 172 | #ifdef CONFIG_X86_32 | ||
| 173 | vm86_trap: | ||
| 174 | if (handle_vm86_trap((struct kernel_vm86_regs *) regs, | ||
| 175 | error_code, trapnr)) | ||
| 176 | goto trap_signal; | ||
| 177 | return; | ||
| 178 | #endif | ||
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | #define DO_ERROR(trapnr, signr, str, name) \ | 179 | #define DO_ERROR(trapnr, signr, str, name) \ |
