]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/traps_32.c
Merge git://git.infradead.org/~dedekind/ubi-2.6
[linux-2.6] / arch / x86 / kernel / traps_32.c
index 3284502a1bf84f730805d3700c75d2bcfc201393..471e694d6713193baa5a25dac995f177ef34abf2 100644 (file)
@@ -498,7 +498,7 @@ do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs *regs,
 {
        struct task_struct *tsk = current;
 
-       if (regs->flags & VM_MASK) {
+       if (regs->flags & X86_VM_MASK) {
                if (vm86)
                        goto vm86_trap;
                goto trap_signal;
@@ -643,7 +643,7 @@ void __kprobes do_general_protection(struct pt_regs *regs, long error_code)
        }
        put_cpu();
 
-       if (regs->flags & VM_MASK)
+       if (regs->flags & X86_VM_MASK)
                goto gp_in_vm86;
 
        if (!user_mode(regs))
@@ -681,7 +681,7 @@ gp_in_kernel:
        }
 }
 
-static __kprobes void
+static notrace __kprobes void
 mem_parity_error(unsigned char reason, struct pt_regs *regs)
 {
        printk(KERN_EMERG
@@ -707,7 +707,7 @@ mem_parity_error(unsigned char reason, struct pt_regs *regs)
        clear_mem_error(reason);
 }
 
-static __kprobes void
+static notrace __kprobes void
 io_check_error(unsigned char reason, struct pt_regs *regs)
 {
        unsigned long i;
@@ -727,9 +727,11 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
        outb(reason, 0x61);
 }
 
-static __kprobes void
+static notrace __kprobes void
 unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
 {
+       if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
+               return;
 #ifdef CONFIG_MCA
        /*
         * Might actually be able to figure out what the guilty party
@@ -753,7 +755,7 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
 
 static DEFINE_SPINLOCK(nmi_print_lock);
 
-void __kprobes die_nmi(struct pt_regs *regs, const char *msg)
+void notrace __kprobes die_nmi(struct pt_regs *regs, const char *msg)
 {
        if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == NOTIFY_STOP)
                return;
@@ -784,7 +786,7 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg)
        do_exit(SIGSEGV);
 }
 
-static __kprobes void default_do_nmi(struct pt_regs *regs)
+static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
 {
        unsigned char reason = 0;
 
@@ -826,7 +828,7 @@ static __kprobes void default_do_nmi(struct pt_regs *regs)
 
 static int ignore_nmis;
 
-__kprobes void do_nmi(struct pt_regs *regs, long error_code)
+notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code)
 {
        int cpu;
 
@@ -922,7 +924,7 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
                        goto clear_dr7;
        }
 
-       if (regs->flags & VM_MASK)
+       if (regs->flags & X86_VM_MASK)
                goto debug_vm86;
 
        /* Save debug status register where ptrace can see it */
@@ -1094,7 +1096,7 @@ void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
         * Handle strange cache flush from user space exception
         * in all other cases.  This is undocumented behaviour.
         */
-       if (regs->flags & VM_MASK) {
+       if (regs->flags & X86_VM_MASK) {
                handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
                return;
        }
@@ -1146,9 +1148,22 @@ asmlinkage void math_state_restore(void)
        struct thread_info *thread = current_thread_info();
        struct task_struct *tsk = thread->task;
 
+       if (!tsk_used_math(tsk)) {
+               local_irq_enable();
+               /*
+                * does a slab alloc which can sleep
+                */
+               if (init_fpu(tsk)) {
+                       /*
+                        * ran out of memory!
+                        */
+                       do_group_exit(SIGKILL);
+                       return;
+               }
+               local_irq_disable();
+       }
+
        clts();                         /* Allow maths ops (or we recurse) */
-       if (!tsk_used_math(tsk))
-               init_fpu(tsk);
        restore_fpu(tsk);
        thread->status |= TS_USEDFPU;   /* So we fnsave on switch_to() */
        tsk->fpu_counter++;
@@ -1206,11 +1221,6 @@ void __init trap_init(void)
 #endif
        set_trap_gate(19, &simd_coprocessor_error);
 
-       /*
-        * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
-        * Generate a build-time error if the alignment is wrong.
-        */
-       BUILD_BUG_ON(offsetof(struct task_struct, thread.i387.fxsave) & 15);
        if (cpu_has_fxsr) {
                printk(KERN_INFO "Enabling fast FPU save and restore... ");
                set_in_cr4(X86_CR4_OSFXSR);
@@ -1231,6 +1241,7 @@ void __init trap_init(void)
 
        set_bit(SYSCALL_VECTOR, used_vectors);
 
+       init_thread_xstate();
        /*
         * Should be a barrier for any external CPU state:
         */