aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/traps.c
diff options
context:
space:
mode:
authorBrian Gerst <brgerst@gmail.com>2010-03-21 09:00:43 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-05-03 16:39:26 -0400
commit40d2e76315da38993129090dc5d56377e573c312 (patch)
tree8f585daa23780aa0841ac72b34053f9deb00041c /arch/x86/kernel/traps.c
parentbe1066bbcd443a65df312fdecea7e4959adedb45 (diff)
x86-32: Rework cache flush denied handler
The cache flush denied error is an erratum on some AMD 486 clones. If an invd instruction is executed in userspace, the processor calls exception 19 (13 hex) instead of #GP (13 decimal). On cpus where XMM is not supported, redirect exception 19 to do_general_protection(). Also, remove die_if_kernel(), since this was the last user. Signed-off-by: Brian Gerst <brgerst@gmail.com> LKML-Reference: <1269176446-2489-2-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/traps.c')
-rw-r--r--arch/x86/kernel/traps.c31
1 files changed, 3 insertions, 28 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 1168e4454188..a16c9dfe6b70 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -108,15 +108,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
108 dec_preempt_count(); 108 dec_preempt_count();
109} 109}
110 110
111#ifdef CONFIG_X86_32
112static inline void
113die_if_kernel(const char *str, struct pt_regs *regs, long err)
114{
115 if (!user_mode_vm(regs))
116 die(str, regs, err);
117}
118#endif
119
120static void __kprobes 111static void __kprobes
121do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, 112do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
122 long error_code, siginfo_t *info) 113 long error_code, siginfo_t *info)
@@ -729,30 +720,14 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
729 conditional_sti(regs); 720 conditional_sti(regs);
730 721
731#ifdef CONFIG_X86_32 722#ifdef CONFIG_X86_32
732 if (cpu_has_xmm) { 723 ignore_fpu_irq = 1;
733 /* Handle SIMD FPU exceptions on PIII+ processors. */
734 ignore_fpu_irq = 1;
735 simd_math_error((void __user *)regs->ip);
736 return;
737 }
738 /*
739 * Handle strange cache flush from user space exception
740 * in all other cases. This is undocumented behaviour.
741 */
742 if (regs->flags & X86_VM_MASK) {
743 handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
744 return;
745 }
746 current->thread.trap_no = 19;
747 current->thread.error_code = error_code;
748 die_if_kernel("cache flush denied", regs, error_code);
749 force_sig(SIGSEGV, current);
750#else 724#else
751 if (!user_mode(regs) && 725 if (!user_mode(regs) &&
752 kernel_math_error(regs, "kernel simd math error", 19)) 726 kernel_math_error(regs, "kernel simd math error", 19))
753 return; 727 return;
754 simd_math_error((void __user *)regs->ip);
755#endif 728#endif
729
730 simd_math_error((void __user *)regs->ip);
756} 731}
757 732
758dotraplinkage void 733dotraplinkage void