Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
[sfrench/cifs-2.6.git] / arch / mips / kernel / unaligned.c
index 5565b89b98e61bf6620297db486382a20fe17759..20709669e5923c0e974a20c3b797b25f24702694 100644 (file)
@@ -101,16 +101,14 @@ static u32 unaligned_action;
 #endif
 extern void show_registers(struct pt_regs *regs);
 
-static inline int emulate_load_store_insn(struct pt_regs *regs,
-       void __user *addr, unsigned int __user *pc,
-       unsigned long **regptr, unsigned long *newvalue)
+static void emulate_load_store_insn(struct pt_regs *regs,
+       void __user *addr, unsigned int __user *pc)
 {
        union mips_instruction insn;
        unsigned long value;
        unsigned int res;
 
        regs->regs[0] = 0;
-       *regptr=NULL;
 
        /*
         * This load never faults.
@@ -179,8 +177,8 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                        : "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
-               *newvalue = value;
-               *regptr = &regs->regs[insn.i_format.rt];
+               compute_return_epc(regs);
+               regs->regs[insn.i_format.rt] = value;
                break;
 
        case lw_op:
@@ -209,8 +207,8 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                        : "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
-               *newvalue = value;
-               *regptr = &regs->regs[insn.i_format.rt];
+               compute_return_epc(regs);
+               regs->regs[insn.i_format.rt] = value;
                break;
 
        case lhu_op:
@@ -243,8 +241,8 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                        : "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
-               *newvalue = value;
-               *regptr = &regs->regs[insn.i_format.rt];
+               compute_return_epc(regs);
+               regs->regs[insn.i_format.rt] = value;
                break;
 
        case lwu_op:
@@ -283,8 +281,8 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                        : "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
-               *newvalue = value;
-               *regptr = &regs->regs[insn.i_format.rt];
+               compute_return_epc(regs);
+               regs->regs[insn.i_format.rt] = value;
                break;
 #endif /* CONFIG_64BIT */
 
@@ -325,8 +323,8 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                        : "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
-               *newvalue = value;
-               *regptr = &regs->regs[insn.i_format.rt];
+               compute_return_epc(regs);
+               regs->regs[insn.i_format.rt] = value;
                break;
 #endif /* CONFIG_64BIT */
 
@@ -367,6 +365,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                        : "r" (value), "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
+               compute_return_epc(regs);
                break;
 
        case sw_op:
@@ -397,6 +396,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                : "r" (value), "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
+               compute_return_epc(regs);
                break;
 
        case sd_op:
@@ -435,6 +435,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
                : "r" (value), "r" (addr), "i" (-EFAULT));
                if (res)
                        goto fault;
+               compute_return_epc(regs);
                break;
 #endif /* CONFIG_64BIT */
 
@@ -473,34 +474,31 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
        unaligned_instructions++;
 #endif
 
-       return 0;
+       return;
 
 fault:
        /* Did we have an exception handler installed? */
        if (fixup_exception(regs))
-               return 1;
+               return;
 
-       die_if_kernel ("Unhandled kernel unaligned access", regs);
+       die_if_kernel("Unhandled kernel unaligned access", regs);
        send_sig(SIGSEGV, current, 1);
 
-       return 0;
+       return;
 
 sigbus:
        die_if_kernel("Unhandled kernel unaligned access", regs);
        send_sig(SIGBUS, current, 1);
 
-       return 0;
+       return;
 
 sigill:
        die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
        send_sig(SIGILL, current, 1);
-
-       return 0;
 }
 
 asmlinkage void do_ade(struct pt_regs *regs)
 {
-       unsigned long *regptr, newval;
        extern int do_dsemulret(struct pt_regs *);
        unsigned int __user *pc;
        mm_segment_t seg;
@@ -538,16 +536,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
        seg = get_fs();
        if (!user_mode(regs))
                set_fs(KERNEL_DS);
-       if (!emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc,
-                                    &regptr, &newval)) {
-               compute_return_epc(regs);
-               /*
-                * Now that branch is evaluated, update the dest
-                * register if necessary
-                */
-               if (regptr)
-                       *regptr = newval;
-       }
+       emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc);
        set_fs(seg);
 
        return;
@@ -571,12 +560,12 @@ static int __init debugfs_unaligned(void)
                return -ENODEV;
        d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
                               mips_debugfs_dir, &unaligned_instructions);
-       if (IS_ERR(d))
-               return PTR_ERR(d);
+       if (!d)
+               return -ENOMEM;
        d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
                               mips_debugfs_dir, &unaligned_action);
-       if (IS_ERR(d))
-               return PTR_ERR(d);
+       if (!d)
+               return -ENOMEM;
        return 0;
 }
 __initcall(debugfs_unaligned);