aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/traps.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-15 06:18:15 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-15 06:18:15 -0400
commitdca2d6ac09d9ef59ff46820d4f0c94b08a671202 (patch)
treefdec753b842dad09e3a4151954fab3eb5c43500d /arch/x86/kernel/traps.c
parentd6a65dffb30d8636b1e5d4c201564ef401a246cf (diff)
parent18240904960a39e582ced8ba8ececb10b8c22dd3 (diff)
Merge branch 'linus' into tracing/hw-breakpoints
Conflicts: arch/x86/kernel/process_64.c Semantic conflict fixed in: arch/x86/kvm/x86.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/traps.c')
-rw-r--r--arch/x86/kernel/traps.c54
1 files changed, 23 insertions, 31 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index ae04589a579b..49a401b1d4d7 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -76,7 +76,7 @@ char ignore_fpu_irq;
76 * F0 0F bug workaround.. We have a special link segment 76 * F0 0F bug workaround.. We have a special link segment
77 * for this. 77 * for this.
78 */ 78 */
79gate_desc idt_table[256] 79gate_desc idt_table[NR_VECTORS]
80 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; 80 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
81#endif 81#endif
82 82
@@ -765,33 +765,34 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
765#endif 765#endif
766} 766}
767 767
768#ifdef CONFIG_X86_32 768asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
769unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
770{ 769{
771 struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
772 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
773 unsigned long new_kesp = kesp - base;
774 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
775 __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
776
777 /* Set up base for espfix segment */
778 desc &= 0x00f0ff0000000000ULL;
779 desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
780 ((((__u64)base) << 32) & 0xff00000000000000ULL) |
781 ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
782 (lim_pages & 0xffff);
783 *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
784
785 return new_kesp;
786} 770}
787#endif
788 771
789asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) 772asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
790{ 773{
791} 774}
792 775
793asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) 776/*
777 * __math_state_restore assumes that cr0.TS is already clear and the
778 * fpu state is all ready for use. Used during context switch.
779 */
780void __math_state_restore(void)
794{ 781{
782 struct thread_info *thread = current_thread_info();
783 struct task_struct *tsk = thread->task;
784
785 /*
786 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
787 */
788 if (unlikely(restore_fpu_checking(tsk))) {
789 stts();
790 force_sig(SIGSEGV, tsk);
791 return;
792 }
793
794 thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
795 tsk->fpu_counter++;
795} 796}
796 797
797/* 798/*
@@ -825,17 +826,8 @@ asmlinkage void math_state_restore(void)
825 } 826 }
826 827
827 clts(); /* Allow maths ops (or we recurse) */ 828 clts(); /* Allow maths ops (or we recurse) */
828 /*
829 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
830 */
831 if (unlikely(restore_fpu_checking(tsk))) {
832 stts();
833 force_sig(SIGSEGV, tsk);
834 return;
835 }
836 829
837 thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ 830 __math_state_restore();
838 tsk->fpu_counter++;
839} 831}
840EXPORT_SYMBOL_GPL(math_state_restore); 832EXPORT_SYMBOL_GPL(math_state_restore);
841 833