Commit 40d2e763 authored by Brian Gerst's avatar Brian Gerst Committed by H. Peter Anvin

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: default avatarBrian Gerst <brgerst@gmail.com>
LKML-Reference: <1269176446-2489-2-git-send-email-brgerst@gmail.com>
Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
parent be1066bb
...@@ -338,6 +338,10 @@ config X86_F00F_BUG ...@@ -338,6 +338,10 @@ config X86_F00F_BUG
def_bool y def_bool y
depends on M586MMX || M586TSC || M586 || M486 || M386 depends on M586MMX || M586TSC || M586 || M486 || M386
config X86_INVD_BUG
def_bool y
depends on M486 || M386
config X86_WP_WORKS_OK config X86_WP_WORKS_OK
def_bool y def_bool y
depends on !M386 depends on !M386
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include <asm/processor-flags.h> #include <asm/processor-flags.h>
#include <asm/ftrace.h> #include <asm/ftrace.h>
#include <asm/irq_vectors.h> #include <asm/irq_vectors.h>
#include <asm/cpufeature.h>
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
#include <linux/elf-em.h> #include <linux/elf-em.h>
...@@ -905,7 +906,25 @@ ENTRY(simd_coprocessor_error) ...@@ -905,7 +906,25 @@ ENTRY(simd_coprocessor_error)
RING0_INT_FRAME RING0_INT_FRAME
pushl $0 pushl $0
CFI_ADJUST_CFA_OFFSET 4 CFI_ADJUST_CFA_OFFSET 4
#ifdef CONFIG_X86_INVD_BUG
/* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
661: pushl $do_general_protection
662:
.section .altinstructions,"a"
.balign 4
.long 661b
.long 663f
.byte X86_FEATURE_XMM
.byte 662b-661b
.byte 664f-663f
.previous
.section .altinstr_replacement,"ax"
663: pushl $do_simd_coprocessor_error
664:
.previous
#else
pushl $do_simd_coprocessor_error pushl $do_simd_coprocessor_error
#endif
CFI_ADJUST_CFA_OFFSET 4 CFI_ADJUST_CFA_OFFSET 4
jmp error_code jmp error_code
CFI_ENDPROC CFI_ENDPROC
......
...@@ -108,15 +108,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) ...@@ -108,15 +108,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
dec_preempt_count(); dec_preempt_count();
} }
#ifdef CONFIG_X86_32
static inline void
die_if_kernel(const char *str, struct pt_regs *regs, long err)
{
if (!user_mode_vm(regs))
die(str, regs, err);
}
#endif
static void __kprobes static void __kprobes
do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
long error_code, siginfo_t *info) long error_code, siginfo_t *info)
...@@ -729,30 +720,14 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code) ...@@ -729,30 +720,14 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
conditional_sti(regs); conditional_sti(regs);
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
if (cpu_has_xmm) { ignore_fpu_irq = 1;
/* Handle SIMD FPU exceptions on PIII+ processors. */
ignore_fpu_irq = 1;
simd_math_error((void __user *)regs->ip);
return;
}
/*
* Handle strange cache flush from user space exception
* in all other cases. This is undocumented behaviour.
*/
if (regs->flags & X86_VM_MASK) {
handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
return;
}
current->thread.trap_no = 19;
current->thread.error_code = error_code;
die_if_kernel("cache flush denied", regs, error_code);
force_sig(SIGSEGV, current);
#else #else
if (!user_mode(regs) && if (!user_mode(regs) &&
kernel_math_error(regs, "kernel simd math error", 19)) kernel_math_error(regs, "kernel simd math error", 19))
return; return;
simd_math_error((void __user *)regs->ip);
#endif #endif
simd_math_error((void __user *)regs->ip);
} }
dotraplinkage void dotraplinkage void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment