Merge branch 'cpus4096-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / arch / x86 / kernel / traps.c
index 04d242a..2d1f4c7 100644 (file)
@@ -72,9 +72,6 @@
 
 #include "cpu/mcheck/mce.h"
 
-DECLARE_BITMAP(used_vectors, NR_VECTORS);
-EXPORT_SYMBOL_GPL(used_vectors);
-
 asmlinkage int system_call(void);
 
 /* Do we ignore FPU interrupts ? */
@@ -89,6 +86,9 @@ gate_desc idt_table[256]
        __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
 #endif
 
+DECLARE_BITMAP(used_vectors, NR_VECTORS);
+EXPORT_SYMBOL_GPL(used_vectors);
+
 static int ignore_nmis;
 
 static inline void conditional_sti(struct pt_regs *regs)
@@ -481,11 +481,7 @@ do_nmi(struct pt_regs *regs, long error_code)
 {
        nmi_enter();
 
-#ifdef CONFIG_X86_32
-       { int cpu; cpu = smp_processor_id(); ++nmi_count(cpu); }
-#else
-       add_pda(__nmi_count, 1);
-#endif
+       inc_irq_stat(__nmi_count);
 
        if (!ignore_nmis)
                default_do_nmi(regs);
@@ -664,7 +660,7 @@ void math_error(void __user *ip)
 {
        struct task_struct *task;
        siginfo_t info;
-       unsigned short cwd, swd;
+       unsigned short cwd, swd, err;
 
        /*
         * Save the info for the exception handler and clear the error.
@@ -675,7 +671,6 @@ void math_error(void __user *ip)
        task->thread.error_code = 0;
        info.si_signo = SIGFPE;
        info.si_errno = 0;
-       info.si_code = __SI_FAULT;
        info.si_addr = ip;
        /*
         * (~cwd & swd) will mask out exceptions that are not set to unmasked
@@ -689,34 +684,31 @@ void math_error(void __user *ip)
         */
        cwd = get_fpu_cwd(task);
        swd = get_fpu_swd(task);
-       switch (swd & ~cwd & 0x3f) {
-       case 0x000: /* No unmasked exception */
+
+       err = swd & ~cwd & 0x3f;
+
 #ifdef CONFIG_X86_32
+       if (!err)
                return;
 #endif
-       default: /* Multiple exceptions */
-               break;
-       case 0x001: /* Invalid Op */
+
+       if (err & 0x001) {      /* Invalid op */
                /*
                 * swd & 0x240 == 0x040: Stack Underflow
                 * swd & 0x240 == 0x240: Stack Overflow
                 * User must clear the SF bit (0x40) if set
                 */
                info.si_code = FPE_FLTINV;
-               break;
-       case 0x002: /* Denormalize */
-       case 0x010: /* Underflow */
-               info.si_code = FPE_FLTUND;
-               break;
-       case 0x004: /* Zero Divide */
+       } else if (err & 0x004) { /* Divide by Zero */
                info.si_code = FPE_FLTDIV;
-               break;
-       case 0x008: /* Overflow */
+       } else if (err & 0x008) { /* Overflow */
                info.si_code = FPE_FLTOVF;
-               break;
-       case 0x020: /* Precision */
+       } else if (err & 0x012) { /* Denormal, Underflow */
+               info.si_code = FPE_FLTUND;
+       } else if (err & 0x020) { /* Precision */
                info.si_code = FPE_FLTRES;
-               break;
+       } else {
+               info.si_code = __SI_FAULT|SI_KERNEL; /* WTF? */
        }
        force_sig_info(SIGFPE, &info, task);
 }
@@ -949,9 +941,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
 
 void __init trap_init(void)
 {
-#ifdef CONFIG_X86_32
        int i;
-#endif
 
 #ifdef CONFIG_EISA
        void __iomem *p = early_ioremap(0x0FFFD9, 4);
@@ -1008,11 +998,15 @@ void __init trap_init(void)
        }
 
        set_system_trap_gate(SYSCALL_VECTOR, &system_call);
+#endif
 
        /* Reserve all the builtin and the syscall vector: */
        for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
                set_bit(i, used_vectors);
 
+#ifdef CONFIG_X86_64
+       set_bit(IA32_SYSCALL_VECTOR, used_vectors);
+#else
        set_bit(SYSCALL_VECTOR, used_vectors);
 #endif
        /*