We were not calling kernel_mna_trap_fault() correctly.
Instead of being fancy, just return 0 vs. -EFAULT from
the assembler stubs, and handle that return value as
appropriate.
Create an "__retl_efault" stub for assembler exception
table entries and use it where possible.
Signed-off-by: David S. Miller <davem@davemloft.net>
 prom_tba:      .xword  0
 tlb_type:      .word   0       /* Must NOT end up in BSS */
        .section        ".fixup",#alloc,#execinstr
-       .globl  __ret_efault
+
+       .globl  __ret_efault, __retl_efault
 __ret_efault:
        ret
         restore %g0, -EFAULT, %o0
-
+__retl_efault:
+       retl
+        mov    -EFAULT, %o0
 
        or              %g2, %lo(__socketcall_table_begin), %g2
        jmpl            %g2 + %o0, %g0
         nop
+do_einval:
+       retl
+        mov            -EINVAL, %o0
 
        .align          32
 __socketcall_table_begin:
        nop
        nop
 
-do_einval:
-       retl
-        mov            -EINVAL, %o0
-do_efault:
-       retl
-        mov            -EFAULT, %o0
-
        .section        __ex_table
        .align          4
-       .word   1b, do_efault, 2b, do_efault, 3b, do_efault, 4b, do_efault
-       .word   5b, do_efault, 6b, do_efault, 7b, do_efault, 8b, do_efault
-       .word   9b, do_efault, 10b, do_efault, 11b, do_efault, 12b, do_efault
-       .word   13b, do_efault, 14b, do_efault, 15b, do_efault, 16b, do_efault
-       .word   17b, do_efault, 18b, do_efault, 19b, do_efault, 20b, do_efault
-       .word   21b, do_efault, 22b, do_efault, 23b, do_efault, 24b, do_efault
-       .word   25b, do_efault, 26b, do_efault, 27b, do_efault, 28b, do_efault
-       .word   29b, do_efault, 30b, do_efault, 31b, do_efault, 32b, do_efault
-       .word   33b, do_efault, 34b, do_efault, 35b, do_efault, 36b, do_efault
-       .word   37b, do_efault, 38b, do_efault, 39b, do_efault, 40b, do_efault
-       .word   41b, do_efault, 42b, do_efault, 43b, do_efault, 44b, do_efault
-       .word   45b, do_efault, 46b, do_efault, 47b, do_efault, 48b, do_efault
-       .word   49b, do_efault, 50b, do_efault, 51b, do_efault, 52b, do_efault
-       .word   53b, do_efault, 54b, do_efault, 55b, do_efault, 56b, do_efault
-       .word   57b, do_efault, 58b, do_efault, 59b, do_efault, 60b, do_efault
-       .word   61b, do_efault, 62b, do_efault
+       .word           1b, __retl_efault, 2b, __retl_efault
+       .word           3b, __retl_efault, 4b, __retl_efault
+       .word           5b, __retl_efault, 6b, __retl_efault
+       .word           7b, __retl_efault, 8b, __retl_efault
+       .word           9b, __retl_efault, 10b, __retl_efault
+       .word           11b, __retl_efault, 12b, __retl_efault
+       .word           13b, __retl_efault, 14b, __retl_efault
+       .word           15b, __retl_efault, 16b, __retl_efault
+       .word           17b, __retl_efault, 18b, __retl_efault
+       .word           19b, __retl_efault, 20b, __retl_efault
+       .word           21b, __retl_efault, 22b, __retl_efault
+       .word           23b, __retl_efault, 24b, __retl_efault
+       .word           25b, __retl_efault, 26b, __retl_efault
+       .word           27b, __retl_efault, 28b, __retl_efault
+       .word           29b, __retl_efault, 30b, __retl_efault
+       .word           31b, __retl_efault, 32b, __retl_efault
+       .word           33b, __retl_efault, 34b, __retl_efault
+       .word           35b, __retl_efault, 36b, __retl_efault
+       .word           37b, __retl_efault, 38b, __retl_efault
+       .word           39b, __retl_efault, 40b, __retl_efault
+       .word           41b, __retl_efault, 42b, __retl_efault
+       .word           43b, __retl_efault, 44b, __retl_efault
+       .word           45b, __retl_efault, 46b, __retl_efault
+       .word           47b, __retl_efault, 48b, __retl_efault
+       .word           49b, __retl_efault, 50b, __retl_efault
+       .word           51b, __retl_efault, 52b, __retl_efault
+       .word           53b, __retl_efault, 54b, __retl_efault
+       .word           55b, __retl_efault, 56b, __retl_efault
+       .word           57b, __retl_efault, 58b, __retl_efault
+       .word           59b, __retl_efault, 60b, __retl_efault
+       .word           61b, __retl_efault, 62b, __retl_efault
        .previous
 
 
        .text
 
-kernel_unaligned_trap_fault:
-       call    kernel_mna_trap_fault
-        nop
-       retl
-        nop
-       .size   kern_unaligned_trap_fault, .-kern_unaligned_trap_fault
-
        .globl  __do_int_store
 __do_int_store:
        rd      %asi, %o4
 0:
        wr      %o4, 0x0, %asi
        retl
-        nop
+        mov    0, %o0
        .size   __do_int_store, .-__do_int_store
 
        .section        __ex_table
-       .word           4b, kernel_unaligned_trap_fault
-       .word           5b, kernel_unaligned_trap_fault
-       .word           6b, kernel_unaligned_trap_fault
-       .word           7b, kernel_unaligned_trap_fault
-       .word           8b, kernel_unaligned_trap_fault
-       .word           9b, kernel_unaligned_trap_fault
-       .word           10b, kernel_unaligned_trap_fault
-       .word           11b, kernel_unaligned_trap_fault
-       .word           12b, kernel_unaligned_trap_fault
-       .word           13b, kernel_unaligned_trap_fault
-       .word           14b, kernel_unaligned_trap_fault
-       .word           15b, kernel_unaligned_trap_fault
-       .word           16b, kernel_unaligned_trap_fault
-       .word           17b, kernel_unaligned_trap_fault
+       .word           4b, __retl_efault
+       .word           5b, __retl_efault
+       .word           6b, __retl_efault
+       .word           7b, __retl_efault
+       .word           8b, __retl_efault
+       .word           9b, __retl_efault
+       .word           10b, __retl_efault
+       .word           11b, __retl_efault
+       .word           12b, __retl_efault
+       .word           13b, __retl_efault
+       .word           14b, __retl_efault
+       .word           15b, __retl_efault
+       .word           16b, __retl_efault
+       .word           17b, __retl_efault
        .previous
 
        .globl  do_int_load
 0:
        wr      %o5, 0x0, %asi
        retl
-        nop
+        mov    0, %o0
        .size   __do_int_load, .-__do_int_load
 
        .section        __ex_table
-       .word           4b, kernel_unaligned_trap_fault
-       .word           5b, kernel_unaligned_trap_fault
-       .word           6b, kernel_unaligned_trap_fault
-       .word           7b, kernel_unaligned_trap_fault
-       .word           8b, kernel_unaligned_trap_fault
-       .word           9b, kernel_unaligned_trap_fault
-       .word           10b, kernel_unaligned_trap_fault
-       .word           11b, kernel_unaligned_trap_fault
-       .word           12b, kernel_unaligned_trap_fault
-       .word           13b, kernel_unaligned_trap_fault
-       .word           14b, kernel_unaligned_trap_fault
-       .word           15b, kernel_unaligned_trap_fault
-       .word           16b, kernel_unaligned_trap_fault
+       .word           4b, __retl_efault
+       .word           5b, __retl_efault
+       .word           6b, __retl_efault
+       .word           7b, __retl_efault
+       .word           8b, __retl_efault
+       .word           9b, __retl_efault
+       .word           10b, __retl_efault
+       .word           11b, __retl_efault
+       .word           12b, __retl_efault
+       .word           13b, __retl_efault
+       .word           14b, __retl_efault
+       .word           15b, __retl_efault
+       .word           16b, __retl_efault
        .previous
 
        die_if_kernel(str, regs);
 }
 
-extern void do_int_load(unsigned long *dest_reg, int size,
-                       unsigned long *saddr, int is_signed, int asi);
+extern int do_int_load(unsigned long *dest_reg, int size,
+                      unsigned long *saddr, int is_signed, int asi);
        
-extern void __do_int_store(unsigned long *dst_addr, int size,
-                          unsigned long src_val, int asi);
+extern int __do_int_store(unsigned long *dst_addr, int size,
+                         unsigned long src_val, int asi);
 
-static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
-                               struct pt_regs *regs, int asi, int orig_asi)
+static inline int do_int_store(int reg_num, int size, unsigned long *dst_addr,
+                              struct pt_regs *regs, int asi, int orig_asi)
 {
        unsigned long zero = 0;
        unsigned long *src_val_p = &zero;
                        break;
                };
        }
-       __do_int_store(dst_addr, size, src_val, asi);
+       return __do_int_store(dst_addr, size, src_val, asi);
 }
 
 static inline void advance(struct pt_regs *regs)
        return !floating_point_load_or_store_p(insn);
 }
 
-void kernel_mna_trap_fault(void)
+static void kernel_mna_trap_fault(void)
 {
        struct pt_regs *regs = current_thread_info()->kern_una_regs;
        unsigned int insn = current_thread_info()->kern_una_insn;
                kernel_mna_trap_fault();
        } else {
                unsigned long addr, *reg_addr;
-               int orig_asi, asi;
+               int orig_asi, asi, err;
 
                addr = compute_effective_address(regs, insn,
                                                 ((insn >> 25) & 0x1f));
                switch (dir) {
                case load:
                        reg_addr = fetch_reg_addr(((insn>>25)&0x1f), regs);
-                       do_int_load(reg_addr, size, (unsigned long *) addr,
-                                   decode_signedness(insn), asi);
-                       if (unlikely(asi != orig_asi)) {
+                       err = do_int_load(reg_addr, size,
+                                         (unsigned long *) addr,
+                                         decode_signedness(insn), asi);
+                       if (likely(!err) && unlikely(asi != orig_asi)) {
                                unsigned long val_in = *reg_addr;
                                switch (size) {
                                case 2:
                        break;
 
                case store:
-                       do_int_store(((insn>>25)&0x1f), size,
-                                    (unsigned long *) addr, regs,
-                                    asi, orig_asi);
+                       err = do_int_store(((insn>>25)&0x1f), size,
+                                          (unsigned long *) addr, regs,
+                                          asi, orig_asi);
                        break;
 
                default:
                        panic("Impossible kernel unaligned trap.");
                        /* Not reached... */
                }
-               advance(regs);
+               if (unlikely(err))
+                       kernel_mna_trap_fault();
+               else
+                       advance(regs);
        }
 }
 
 
         add    %o2, %o3, %o0
        .size   __strncpy_from_user, .-__strncpy_from_user
 
-       .section .fixup,#alloc,#execinstr
-       .align  4
-4:     retl
-        mov    -EFAULT, %o0
-
        .section __ex_table,#alloc
        .align  4
-       .word   60b, 4b
-       .word   61b, 4b
-       .word   62b, 4b
-       .word   63b, 4b
-       .word   64b, 4b
+       .word   60b, __retl_efault
+       .word   61b, __retl_efault
+       .word   62b, __retl_efault
+       .word   63b, __retl_efault
+       .word   64b, __retl_efault
+       .previous
 
 };
 
 extern void __ret_efault(void);
+extern void __retl_efault(void);
 
 /* Uh, these should become the main single-value transfer routines..
  * They automatically use the right size if we just have the right