]> err.no Git - linux-2.6/blobdiff - arch/i386/kernel/traps.c
Merge HEAD from master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
[linux-2.6] / arch / i386 / kernel / traps.c
index e458463ebc0560257e328617ee77afa5e9badf88..cd2d5d5514fe0ffcdf78cadfbabdf5863ede040c 100644 (file)
@@ -235,22 +235,22 @@ void show_registers(struct pt_regs *regs)
         * time of the fault..
         */
        if (in_kernel) {
-               u8 *eip;
+               u8 __user *eip;
 
                printk("\nStack: ");
                show_stack(NULL, (unsigned long*)esp);
 
                printk("Code: ");
 
-               eip = (u8 *)regs->eip - 43;
+               eip = (u8 __user *)regs->eip - 43;
                for (i = 0; i < 64; i++, eip++) {
                        unsigned char c;
 
-                       if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) {
+                       if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
                                printk(" Bad EIP value.");
                                break;
                        }
-                       if (eip == (u8 *)regs->eip)
+                       if (eip == (u8 __user *)regs->eip)
                                printk("<%02x> ", c);
                        else
                                printk("%02x ", c);
@@ -274,13 +274,13 @@ static void handle_BUG(struct pt_regs *regs)
 
        if (eip < PAGE_OFFSET)
                goto no_bug;
-       if (__get_user(ud2, (unsigned short *)eip))
+       if (__get_user(ud2, (unsigned short __user *)eip))
                goto no_bug;
        if (ud2 != 0x0b0f)
                goto no_bug;
-       if (__get_user(line, (unsigned short *)(eip + 2)))
+       if (__get_user(line, (unsigned short __user *)(eip + 2)))
                goto bug;
-       if (__get_user(file, (char **)(eip + 4)) ||
+       if (__get_user(file, (char * __user *)(eip + 4)) ||
                (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
                file = "<bad filename>";
 
@@ -369,6 +369,10 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e
 static void do_trap(int trapnr, int signr, char *str, int vm86,
                           struct pt_regs * regs, long error_code, siginfo_t *info)
 {
+       struct task_struct *tsk = current;
+       tsk->thread.error_code = error_code;
+       tsk->thread.trap_no = trapnr;
+
        if (regs->eflags & VM_MASK) {
                if (vm86)
                        goto vm86_trap;
@@ -379,9 +383,6 @@ static void do_trap(int trapnr, int signr, char *str, int vm86,
                goto kernel_trap;
 
        trap_signal: {
-               struct task_struct *tsk = current;
-               tsk->thread.error_code = error_code;
-               tsk->thread.trap_no = trapnr;
                if (info)
                        force_sig_info(signr, info, tsk);
                else
@@ -494,6 +495,9 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
        }
        put_cpu();
 
+       current->thread.error_code = error_code;
+       current->thread.trap_no = 13;
+
        if (regs->eflags & VM_MASK)
                goto gp_in_vm86;
 
@@ -799,15 +803,17 @@ void math_error(void __user *eip)
         */
        cwd = get_fpu_cwd(task);
        swd = get_fpu_swd(task);
-       switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
+       switch (swd & ~cwd & 0x3f) {
                case 0x000:
                default:
                        break;
                case 0x001: /* Invalid Op */
-               case 0x041: /* Stack Fault */
-               case 0x241: /* Stack Fault | Direction */
+                       /*
+                        * swd & 0x240 == 0x040: Stack Underflow
+                        * swd & 0x240 == 0x240: Stack Overflow
+                        * User must clear the SF bit (0x40) if set
+                        */
                        info.si_code = FPE_FLTINV;
-                       /* Should we clear the SF or let user space do it ???? */
                        break;
                case 0x002: /* Denormalize */
                case 0x010: /* Underflow */
@@ -897,9 +903,9 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
                                          error_code);
                        return;
                }
-               die_if_kernel("cache flush denied", regs, error_code);
                current->thread.trap_no = 19;
                current->thread.error_code = error_code;
+               die_if_kernel("cache flush denied", regs, error_code);
                force_sig(SIGSEGV, current);
        }
 }