diff options
Diffstat (limited to 'arch/x86/kernel/traps.c')
-rw-r--r-- | arch/x86/kernel/traps.c | 65 |
1 files changed, 26 insertions, 39 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 5204332f475d..7e37dcee0cc3 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/kprobes.h> | 15 | #include <linux/kprobes.h> |
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <linux/utsname.h> | ||
18 | #include <linux/kdebug.h> | 17 | #include <linux/kdebug.h> |
19 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -59,12 +58,12 @@ | |||
59 | #include <asm/mach_traps.h> | 58 | #include <asm/mach_traps.h> |
60 | 59 | ||
61 | #ifdef CONFIG_X86_64 | 60 | #ifdef CONFIG_X86_64 |
61 | #include <asm/x86_init.h> | ||
62 | #include <asm/pgalloc.h> | 62 | #include <asm/pgalloc.h> |
63 | #include <asm/proto.h> | 63 | #include <asm/proto.h> |
64 | #else | 64 | #else |
65 | #include <asm/processor-flags.h> | 65 | #include <asm/processor-flags.h> |
66 | #include <asm/setup.h> | 66 | #include <asm/setup.h> |
67 | #include <asm/traps.h> | ||
68 | 67 | ||
69 | asmlinkage int system_call(void); | 68 | asmlinkage int system_call(void); |
70 | 69 | ||
@@ -73,11 +72,9 @@ char ignore_fpu_irq; | |||
73 | 72 | ||
74 | /* | 73 | /* |
75 | * The IDT has to be page-aligned to simplify the Pentium | 74 | * The IDT has to be page-aligned to simplify the Pentium |
76 | * F0 0F bug workaround.. We have a special link segment | 75 | * F0 0F bug workaround. |
77 | * for this. | ||
78 | */ | 76 | */ |
79 | gate_desc idt_table[256] | 77 | gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, }; |
80 | __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; | ||
81 | #endif | 78 | #endif |
82 | 79 | ||
83 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | 80 | DECLARE_BITMAP(used_vectors, NR_VECTORS); |
@@ -786,33 +783,34 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) | |||
786 | #endif | 783 | #endif |
787 | } | 784 | } |
788 | 785 | ||
789 | #ifdef CONFIG_X86_32 | 786 | asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) |
790 | unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) | ||
791 | { | 787 | { |
792 | struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id()); | ||
793 | unsigned long base = (kesp - uesp) & -THREAD_SIZE; | ||
794 | unsigned long new_kesp = kesp - base; | ||
795 | unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; | ||
796 | __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; | ||
797 | |||
798 | /* Set up base for espfix segment */ | ||
799 | desc &= 0x00f0ff0000000000ULL; | ||
800 | desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) | | ||
801 | ((((__u64)base) << 32) & 0xff00000000000000ULL) | | ||
802 | ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) | | ||
803 | (lim_pages & 0xffff); | ||
804 | *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc; | ||
805 | |||
806 | return new_kesp; | ||
807 | } | 788 | } |
808 | #endif | ||
809 | 789 | ||
810 | asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) | 790 | asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) |
811 | { | 791 | { |
812 | } | 792 | } |
813 | 793 | ||
814 | asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) | 794 | /* |
795 | * __math_state_restore assumes that cr0.TS is already clear and the | ||
796 | * fpu state is all ready for use. Used during context switch. | ||
797 | */ | ||
798 | void __math_state_restore(void) | ||
815 | { | 799 | { |
800 | struct thread_info *thread = current_thread_info(); | ||
801 | struct task_struct *tsk = thread->task; | ||
802 | |||
803 | /* | ||
804 | * Paranoid restore. send a SIGSEGV if we fail to restore the state. | ||
805 | */ | ||
806 | if (unlikely(restore_fpu_checking(tsk))) { | ||
807 | stts(); | ||
808 | force_sig(SIGSEGV, tsk); | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ | ||
813 | tsk->fpu_counter++; | ||
816 | } | 814 | } |
817 | 815 | ||
818 | /* | 816 | /* |
@@ -846,17 +844,8 @@ asmlinkage void math_state_restore(void) | |||
846 | } | 844 | } |
847 | 845 | ||
848 | clts(); /* Allow maths ops (or we recurse) */ | 846 | clts(); /* Allow maths ops (or we recurse) */ |
849 | /* | ||
850 | * Paranoid restore. send a SIGSEGV if we fail to restore the state. | ||
851 | */ | ||
852 | if (unlikely(restore_fpu_checking(tsk))) { | ||
853 | stts(); | ||
854 | force_sig(SIGSEGV, tsk); | ||
855 | return; | ||
856 | } | ||
857 | 847 | ||
858 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ | 848 | __math_state_restore(); |
859 | tsk->fpu_counter++; | ||
860 | } | 849 | } |
861 | EXPORT_SYMBOL_GPL(math_state_restore); | 850 | EXPORT_SYMBOL_GPL(math_state_restore); |
862 | 851 | ||
@@ -980,7 +969,5 @@ void __init trap_init(void) | |||
980 | */ | 969 | */ |
981 | cpu_init(); | 970 | cpu_init(); |
982 | 971 | ||
983 | #ifdef CONFIG_X86_32 | 972 | x86_init.irqs.trap_init(); |
984 | x86_quirk_trap_init(); | ||
985 | #endif | ||
986 | } | 973 | } |