diff options
Diffstat (limited to 'arch/x86/kernel/traps.c')
-rw-r--r-- | arch/x86/kernel/traps.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 98c2d055284b..c05430ac1b44 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -54,15 +54,14 @@ | |||
54 | #include <asm/desc.h> | 54 | #include <asm/desc.h> |
55 | #include <asm/i387.h> | 55 | #include <asm/i387.h> |
56 | 56 | ||
57 | #include <mach_traps.h> | 57 | #include <asm/mach_traps.h> |
58 | 58 | ||
59 | #ifdef CONFIG_X86_64 | 59 | #ifdef CONFIG_X86_64 |
60 | #include <asm/pgalloc.h> | 60 | #include <asm/pgalloc.h> |
61 | #include <asm/proto.h> | 61 | #include <asm/proto.h> |
62 | #include <asm/pda.h> | ||
63 | #else | 62 | #else |
64 | #include <asm/processor-flags.h> | 63 | #include <asm/processor-flags.h> |
65 | #include <asm/arch_hooks.h> | 64 | #include <asm/setup.h> |
66 | #include <asm/traps.h> | 65 | #include <asm/traps.h> |
67 | 66 | ||
68 | #include "cpu/mcheck/mce.h" | 67 | #include "cpu/mcheck/mce.h" |
@@ -99,6 +98,12 @@ static inline void preempt_conditional_sti(struct pt_regs *regs) | |||
99 | local_irq_enable(); | 98 | local_irq_enable(); |
100 | } | 99 | } |
101 | 100 | ||
101 | static inline void conditional_cli(struct pt_regs *regs) | ||
102 | { | ||
103 | if (regs->flags & X86_EFLAGS_IF) | ||
104 | local_irq_disable(); | ||
105 | } | ||
106 | |||
102 | static inline void preempt_conditional_cli(struct pt_regs *regs) | 107 | static inline void preempt_conditional_cli(struct pt_regs *regs) |
103 | { | 108 | { |
104 | if (regs->flags & X86_EFLAGS_IF) | 109 | if (regs->flags & X86_EFLAGS_IF) |
@@ -626,8 +631,10 @@ clear_dr7: | |||
626 | 631 | ||
627 | #ifdef CONFIG_X86_32 | 632 | #ifdef CONFIG_X86_32 |
628 | debug_vm86: | 633 | debug_vm86: |
634 | /* reenable preemption: handle_vm86_trap() might sleep */ | ||
635 | dec_preempt_count(); | ||
629 | handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); | 636 | handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); |
630 | preempt_conditional_cli(regs); | 637 | conditional_cli(regs); |
631 | return; | 638 | return; |
632 | #endif | 639 | #endif |
633 | 640 | ||
@@ -896,7 +903,7 @@ asmlinkage void math_state_restore(void) | |||
896 | EXPORT_SYMBOL_GPL(math_state_restore); | 903 | EXPORT_SYMBOL_GPL(math_state_restore); |
897 | 904 | ||
898 | #ifndef CONFIG_MATH_EMULATION | 905 | #ifndef CONFIG_MATH_EMULATION |
899 | asmlinkage void math_emulate(long arg) | 906 | void math_emulate(struct math_emu_info *info) |
900 | { | 907 | { |
901 | printk(KERN_EMERG | 908 | printk(KERN_EMERG |
902 | "math-emulation not enabled and no coprocessor found.\n"); | 909 | "math-emulation not enabled and no coprocessor found.\n"); |
@@ -907,12 +914,16 @@ asmlinkage void math_emulate(long arg) | |||
907 | #endif /* CONFIG_MATH_EMULATION */ | 914 | #endif /* CONFIG_MATH_EMULATION */ |
908 | 915 | ||
909 | dotraplinkage void __kprobes | 916 | dotraplinkage void __kprobes |
910 | do_device_not_available(struct pt_regs *regs, long error) | 917 | do_device_not_available(struct pt_regs *regs, long error_code) |
911 | { | 918 | { |
912 | #ifdef CONFIG_X86_32 | 919 | #ifdef CONFIG_X86_32 |
913 | if (read_cr0() & X86_CR0_EM) { | 920 | if (read_cr0() & X86_CR0_EM) { |
921 | struct math_emu_info info = { }; | ||
922 | |||
914 | conditional_sti(regs); | 923 | conditional_sti(regs); |
915 | math_emulate(0); | 924 | |
925 | info.regs = regs; | ||
926 | math_emulate(&info); | ||
916 | } else { | 927 | } else { |
917 | math_state_restore(); /* interrupts still off */ | 928 | math_state_restore(); /* interrupts still off */ |
918 | conditional_sti(regs); | 929 | conditional_sti(regs); |
@@ -931,7 +942,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | |||
931 | info.si_signo = SIGILL; | 942 | info.si_signo = SIGILL; |
932 | info.si_errno = 0; | 943 | info.si_errno = 0; |
933 | info.si_code = ILL_BADSTK; | 944 | info.si_code = ILL_BADSTK; |
934 | info.si_addr = 0; | 945 | info.si_addr = NULL; |
935 | if (notify_die(DIE_TRAP, "iret exception", | 946 | if (notify_die(DIE_TRAP, "iret exception", |
936 | regs, error_code, 32, SIGILL) == NOTIFY_STOP) | 947 | regs, error_code, 32, SIGILL) == NOTIFY_STOP) |
937 | return; | 948 | return; |
@@ -1015,6 +1026,6 @@ void __init trap_init(void) | |||
1015 | cpu_init(); | 1026 | cpu_init(); |
1016 | 1027 | ||
1017 | #ifdef CONFIG_X86_32 | 1028 | #ifdef CONFIG_X86_32 |
1018 | trap_init_hook(); | 1029 | x86_quirk_trap_init(); |
1019 | #endif | 1030 | #endif |
1020 | } | 1031 | } |