aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/traps.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2012-09-25 08:51:19 -0400
committerIngo Molnar <mingo@kernel.org>2012-09-26 07:36:50 -0400
commitc416ddf5b909736f5b57d348f5de159693e699ad (patch)
treec552314d78d7950a9751cc18f394b5daa5ce2327 /arch/x86/kernel/traps.c
parent1b2b23d8573076a587ed2081e0d2b69691079e0e (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.c60
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
110static void __kprobes 110static int __kprobes
111do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, 111do_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 140static void __kprobes
132trap_signal: 141do_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
163kernel_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
172vm86_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) \