]> err.no Git - linux-2.6/blobdiff - arch/i386/kernel/traps.c
[PATCH] i386: move SIMD initialization
[linux-2.6] / arch / i386 / kernel / traps.c
index 431a551e46ea5f191498eaa6fbe7a6fc7d7273fa..f0c4060bd4d5feace1c91e958906cf423bdf3f5c 100644 (file)
@@ -52,7 +52,6 @@
 #include <asm/arch_hooks.h>
 #include <asm/kdebug.h>
 
-#include <linux/irq.h>
 #include <linux/module.h>
 
 #include "mach_traps.h"
@@ -307,14 +306,17 @@ void die(const char * str, struct pt_regs * regs, long err)
                .lock_owner_depth =     0
        };
        static int die_counter;
+       unsigned long flags;
 
        if (die.lock_owner != raw_smp_processor_id()) {
                console_verbose();
-               spin_lock_irq(&die.lock);
+               spin_lock_irqsave(&die.lock, flags);
                die.lock_owner = smp_processor_id();
                die.lock_owner_depth = 0;
                bust_spinlocks(1);
        }
+       else
+               local_save_flags(flags);
 
        if (++die.lock_owner_depth < 3) {
                int nl = 0;
@@ -341,7 +343,7 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        bust_spinlocks(0);
        die.lock_owner = -1;
-       spin_unlock_irq(&die.lock);
+       spin_unlock_irqrestore(&die.lock, flags);
 
        if (kexec_should_crash(current))
                crash_kexec(regs);
@@ -453,7 +455,7 @@ DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
 #endif
 DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
 DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
-DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
+DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip)
 DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
 DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
@@ -489,6 +491,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
                                tss->io_bitmap_max - thread->io_bitmap_max);
                tss->io_bitmap_max = thread->io_bitmap_max;
                tss->io_bitmap_base = IO_BITMAP_OFFSET;
+               tss->io_bitmap_owner = thread;
                put_cpu();
                return;
        }
@@ -650,13 +653,6 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
 
        cpu = smp_processor_id();
 
-#ifdef CONFIG_HOTPLUG_CPU
-       if (!cpu_online(cpu)) {
-               nmi_exit();
-               return;
-       }
-#endif
-
        ++nmi_count(cpu);
 
        if (!rcu_dereference(nmi_callback)(regs, cpu))
@@ -1102,6 +1098,28 @@ void __init trap_init(void)
 #endif
        set_trap_gate(19,&simd_coprocessor_error);
 
+       if (cpu_has_fxsr) {
+               /*
+                * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
+                * Generates a compile-time "error: zero width for bit-field" if
+                * the alignment is wrong.
+                */
+               struct fxsrAlignAssert {
+                       int _:!(offsetof(struct task_struct,
+                                       thread.i387.fxsave) & 15);
+               };
+
+               printk(KERN_INFO "Enabling fast FPU save and restore... ");
+               set_in_cr4(X86_CR4_OSFXSR);
+               printk("done.\n");
+       }
+       if (cpu_has_xmm) {
+               printk(KERN_INFO "Enabling unmasked SIMD FPU exception "
+                               "support... ");
+               set_in_cr4(X86_CR4_OSXMMEXCPT);
+               printk("done.\n");
+       }
+
        set_system_gate(SYSCALL_VECTOR,&system_call);
 
        /*