diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 13:46:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 13:46:27 -0400 |
commit | da8347969f324db5f572581397d9b3a8e108cda4 (patch) | |
tree | 7df2ea8968ecb92e307bbffdbe8f9bcd0c79c36a /arch/x86/kernel/traps.c | |
parent | 80749df4a1492004fdb7bd2cec094b92260c6d27 (diff) | |
parent | c416ddf5b909736f5b57d348f5de159693e699ad (diff) |
Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86/asm changes from Ingo Molnar:
"The one change that stands out is the alternatives patching change
that prevents us from ever patching back instructions from SMP to UP:
this simplifies things and speeds up CPU hotplug.
Other than that it's smaller fixes, cleanups and improvements."
* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86: Unspaghettize do_trap()
x86_64: Work around old GAS bug
x86: Use REP BSF unconditionally
x86: Prefer TZCNT over BFS
x86/64: Adjust types of temporaries used by ffs()/fls()/fls64()
x86: Drop unnecessary kernel_eflags variable on 64-bit
x86/smp: Don't ever patch back to UP if we unplug cpus
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) \ |