diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2012-09-25 08:51:19 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-09-26 07:36:50 -0400 |
commit | c416ddf5b909736f5b57d348f5de159693e699ad (patch) | |
tree | c552314d78d7950a9751cc18f394b5daa5ce2327 /arch/x86/kernel/traps.c | |
parent | 1b2b23d8573076a587ed2081e0d2b69691079e0e (diff) |
x86: Unspaghettize do_trap()
Cleanup the label maze in this function. Having a
seperate function to first handle the traps that don't
generate a signal makes it easier to convert into
more readable conditional paths.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1348577479-2564-1-git-send-email-fweisbec@gmail.com
[ Fixed 32-bit build failure. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
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 b481341c9369..6ff771559af3 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -107,30 +107,45 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) | |||
107 | dec_preempt_count(); | 107 | dec_preempt_count(); |
108 | } | 108 | } |
109 | 109 | ||
110 | static void __kprobes | 110 | static int __kprobes |
111 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | 111 | do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, |
112 | long error_code, siginfo_t *info) | 112 | struct pt_regs *regs, long error_code) |
113 | { | 113 | { |
114 | struct task_struct *tsk = current; | ||
115 | |||
116 | #ifdef CONFIG_X86_32 | 114 | #ifdef CONFIG_X86_32 |
117 | if (regs->flags & X86_VM_MASK) { | 115 | if (regs->flags & X86_VM_MASK) { |
118 | /* | 116 | /* |
119 | * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. | 117 | * Traps 0, 1, 3, 4, and 5 should be forwarded to vm86. |
120 | * On nmi (interrupt 2), do_trap should not be called. | 118 | * On nmi (interrupt 2), do_trap should not be called. |
121 | */ | 119 | */ |
122 | if (trapnr < X86_TRAP_UD) | 120 | if (trapnr < X86_TRAP_UD) { |
123 | goto vm86_trap; | 121 | if (!handle_vm86_trap((struct kernel_vm86_regs *) regs, |
124 | goto trap_signal; | 122 | error_code, trapnr)) |
123 | return 0; | ||
124 | } | ||
125 | return -1; | ||
125 | } | 126 | } |
126 | #endif | 127 | #endif |
128 | if (!user_mode(regs)) { | ||
129 | if (!fixup_exception(regs)) { | ||
130 | tsk->thread.error_code = error_code; | ||
131 | tsk->thread.trap_nr = trapnr; | ||
132 | die(str, regs, error_code); | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
127 | 136 | ||
128 | if (!user_mode(regs)) | 137 | return -1; |
129 | goto kernel_trap; | 138 | } |
130 | 139 | ||
131 | #ifdef CONFIG_X86_32 | 140 | static void __kprobes |
132 | trap_signal: | 141 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, |
133 | #endif | 142 | long error_code, siginfo_t *info) |
143 | { | ||
144 | struct task_struct *tsk = current; | ||
145 | |||
146 | |||
147 | if (!do_trap_no_signal(tsk, trapnr, str, regs, error_code)) | ||
148 | return; | ||
134 | /* | 149 | /* |
135 | * We want error_code and trap_nr set for userspace faults and | 150 | * We want error_code and trap_nr set for userspace faults and |
136 | * kernelspace faults which result in die(), but not | 151 | * kernelspace faults which result in die(), but not |
@@ -158,23 +173,6 @@ trap_signal: | |||
158 | force_sig_info(signr, info, tsk); | 173 | force_sig_info(signr, info, tsk); |
159 | else | 174 | else |
160 | force_sig(signr, tsk); | 175 | force_sig(signr, tsk); |
161 | return; | ||
162 | |||
163 | kernel_trap: | ||
164 | if (!fixup_exception(regs)) { | ||
165 | tsk->thread.error_code = error_code; | ||
166 | tsk->thread.trap_nr = trapnr; | ||
167 | die(str, regs, error_code); | ||
168 | } | ||
169 | return; | ||
170 | |||
171 | #ifdef CONFIG_X86_32 | ||
172 | vm86_trap: | ||
173 | if (handle_vm86_trap((struct kernel_vm86_regs *) regs, | ||
174 | error_code, trapnr)) | ||
175 | goto trap_signal; | ||
176 | return; | ||
177 | #endif | ||
178 | } | 176 | } |
179 | 177 | ||
180 | #define DO_ERROR(trapnr, signr, str, name) \ | 178 | #define DO_ERROR(trapnr, signr, str, name) \ |