[SPARC64]: Fix fault handling in unaligned trap handler.

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>

+95 -87
+5 -2
arch/sparc64/kernel/head.S
··· 540 prom_tba: .xword 0 541 tlb_type: .word 0 /* Must NOT end up in BSS */ 542 .section ".fixup",#alloc,#execinstr 543 - .globl __ret_efault 544 __ret_efault: 545 ret 546 restore %g0, -EFAULT, %o0 547 -
··· 540 prom_tba: .xword 0 541 tlb_type: .word 0 /* Must NOT end up in BSS */ 542 .section ".fixup",#alloc,#execinstr 543 + 544 + .globl __ret_efault, __retl_efault 545 __ret_efault: 546 ret 547 restore %g0, -EFAULT, %o0 548 + __retl_efault: 549 + retl 550 + mov -EFAULT, %o0
+34 -23
arch/sparc64/kernel/sys32.S
··· 157 or %g2, %lo(__socketcall_table_begin), %g2 158 jmpl %g2 + %o0, %g0 159 nop 160 161 .align 32 162 __socketcall_table_begin: ··· 319 nop 320 nop 321 322 - do_einval: 323 - retl 324 - mov -EINVAL, %o0 325 - do_efault: 326 - retl 327 - mov -EFAULT, %o0 328 - 329 .section __ex_table 330 .align 4 331 - .word 1b, do_efault, 2b, do_efault, 3b, do_efault, 4b, do_efault 332 - .word 5b, do_efault, 6b, do_efault, 7b, do_efault, 8b, do_efault 333 - .word 9b, do_efault, 10b, do_efault, 11b, do_efault, 12b, do_efault 334 - .word 13b, do_efault, 14b, do_efault, 15b, do_efault, 16b, do_efault 335 - .word 17b, do_efault, 18b, do_efault, 19b, do_efault, 20b, do_efault 336 - .word 21b, do_efault, 22b, do_efault, 23b, do_efault, 24b, do_efault 337 - .word 25b, do_efault, 26b, do_efault, 27b, do_efault, 28b, do_efault 338 - .word 29b, do_efault, 30b, do_efault, 31b, do_efault, 32b, do_efault 339 - .word 33b, do_efault, 34b, do_efault, 35b, do_efault, 36b, do_efault 340 - .word 37b, do_efault, 38b, do_efault, 39b, do_efault, 40b, do_efault 341 - .word 41b, do_efault, 42b, do_efault, 43b, do_efault, 44b, do_efault 342 - .word 45b, do_efault, 46b, do_efault, 47b, do_efault, 48b, do_efault 343 - .word 49b, do_efault, 50b, do_efault, 51b, do_efault, 52b, do_efault 344 - .word 53b, do_efault, 54b, do_efault, 55b, do_efault, 56b, do_efault 345 - .word 57b, do_efault, 58b, do_efault, 59b, do_efault, 60b, do_efault 346 - .word 61b, do_efault, 62b, do_efault 347 .previous
··· 157 or %g2, %lo(__socketcall_table_begin), %g2 158 jmpl %g2 + %o0, %g0 159 nop 160 + do_einval: 161 + retl 162 + mov -EINVAL, %o0 163 164 .align 32 165 __socketcall_table_begin: ··· 316 nop 317 nop 318 319 .section __ex_table 320 .align 4 321 + .word 1b, __retl_efault, 2b, __retl_efault 322 + .word 3b, __retl_efault, 4b, __retl_efault 323 + .word 5b, __retl_efault, 6b, __retl_efault 324 + .word 7b, __retl_efault, 8b, __retl_efault 325 + .word 9b, __retl_efault, 10b, __retl_efault 326 + .word 11b, __retl_efault, 12b, __retl_efault 327 + .word 13b, __retl_efault, 14b, __retl_efault 328 + .word 15b, __retl_efault, 16b, __retl_efault 329 + .word 17b, __retl_efault, 18b, __retl_efault 330 + .word 19b, __retl_efault, 20b, __retl_efault 331 + .word 21b, __retl_efault, 22b, __retl_efault 332 + .word 23b, __retl_efault, 24b, __retl_efault 333 + .word 25b, __retl_efault, 26b, __retl_efault 334 + .word 27b, __retl_efault, 28b, __retl_efault 335 + .word 29b, __retl_efault, 30b, __retl_efault 336 + .word 31b, __retl_efault, 32b, __retl_efault 337 + .word 33b, __retl_efault, 34b, __retl_efault 338 + .word 35b, __retl_efault, 36b, __retl_efault 339 + .word 37b, __retl_efault, 38b, __retl_efault 340 + .word 39b, __retl_efault, 40b, __retl_efault 341 + .word 41b, __retl_efault, 42b, __retl_efault 342 + .word 43b, __retl_efault, 44b, __retl_efault 343 + .word 45b, __retl_efault, 46b, __retl_efault 344 + .word 47b, __retl_efault, 48b, __retl_efault 345 + .word 49b, __retl_efault, 50b, __retl_efault 346 + .word 51b, __retl_efault, 52b, __retl_efault 347 + .word 53b, __retl_efault, 54b, __retl_efault 348 + .word 55b, __retl_efault, 56b, __retl_efault 349 + .word 57b, __retl_efault, 58b, __retl_efault 350 + .word 59b, __retl_efault, 60b, __retl_efault 351 + .word 61b, __retl_efault, 62b, __retl_efault 352 .previous
+29 -36
arch/sparc64/kernel/una_asm.S
··· 6 7 .text 8 9 - kernel_unaligned_trap_fault: 10 - call kernel_mna_trap_fault 11 - nop 12 - retl 13 - nop 14 - .size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault 15 - 16 .globl __do_int_store 17 __do_int_store: 18 rd %asi, %o4 ··· 44 0: 45 wr %o4, 0x0, %asi 46 retl 47 - nop 48 .size __do_int_store, .-__do_int_store 49 50 .section __ex_table 51 - .word 4b, kernel_unaligned_trap_fault 52 - .word 5b, kernel_unaligned_trap_fault 53 - .word 6b, kernel_unaligned_trap_fault 54 - .word 7b, kernel_unaligned_trap_fault 55 - .word 8b, kernel_unaligned_trap_fault 56 - .word 9b, kernel_unaligned_trap_fault 57 - .word 10b, kernel_unaligned_trap_fault 58 - .word 11b, kernel_unaligned_trap_fault 59 - .word 12b, kernel_unaligned_trap_fault 60 - .word 13b, kernel_unaligned_trap_fault 61 - .word 14b, kernel_unaligned_trap_fault 62 - .word 15b, kernel_unaligned_trap_fault 63 - .word 16b, kernel_unaligned_trap_fault 64 - .word 17b, kernel_unaligned_trap_fault 65 .previous 66 67 .globl do_int_load ··· 126 0: 127 wr %o5, 0x0, %asi 128 retl 129 - nop 130 .size __do_int_load, .-__do_int_load 131 132 .section __ex_table 133 - .word 4b, kernel_unaligned_trap_fault 134 - .word 5b, kernel_unaligned_trap_fault 135 - .word 6b, kernel_unaligned_trap_fault 136 - .word 7b, kernel_unaligned_trap_fault 137 - .word 8b, kernel_unaligned_trap_fault 138 - .word 9b, kernel_unaligned_trap_fault 139 - .word 10b, kernel_unaligned_trap_fault 140 - .word 11b, kernel_unaligned_trap_fault 141 - .word 12b, kernel_unaligned_trap_fault 142 - .word 13b, kernel_unaligned_trap_fault 143 - .word 14b, kernel_unaligned_trap_fault 144 - .word 15b, kernel_unaligned_trap_fault 145 - .word 16b, kernel_unaligned_trap_fault 146 .previous
··· 6 7 .text 8 9 .globl __do_int_store 10 __do_int_store: 11 rd %asi, %o4 ··· 51 0: 52 wr %o4, 0x0, %asi 53 retl 54 + mov 0, %o0 55 .size __do_int_store, .-__do_int_store 56 57 .section __ex_table 58 + .word 4b, __retl_efault 59 + .word 5b, __retl_efault 60 + .word 6b, __retl_efault 61 + .word 7b, __retl_efault 62 + .word 8b, __retl_efault 63 + .word 9b, __retl_efault 64 + .word 10b, __retl_efault 65 + .word 11b, __retl_efault 66 + .word 12b, __retl_efault 67 + .word 13b, __retl_efault 68 + .word 14b, __retl_efault 69 + .word 15b, __retl_efault 70 + .word 16b, __retl_efault 71 + .word 17b, __retl_efault 72 .previous 73 74 .globl do_int_load ··· 133 0: 134 wr %o5, 0x0, %asi 135 retl 136 + mov 0, %o0 137 .size __do_int_load, .-__do_int_load 138 139 .section __ex_table 140 + .word 4b, __retl_efault 141 + .word 5b, __retl_efault 142 + .word 6b, __retl_efault 143 + .word 7b, __retl_efault 144 + .word 8b, __retl_efault 145 + .word 9b, __retl_efault 146 + .word 10b, __retl_efault 147 + .word 11b, __retl_efault 148 + .word 12b, __retl_efault 149 + .word 13b, __retl_efault 150 + .word 14b, __retl_efault 151 + .word 15b, __retl_efault 152 + .word 16b, __retl_efault 153 .previous
+20 -16
arch/sparc64/kernel/unaligned.c
··· 180 die_if_kernel(str, regs); 181 } 182 183 - extern void do_int_load(unsigned long *dest_reg, int size, 184 - unsigned long *saddr, int is_signed, int asi); 185 186 - extern void __do_int_store(unsigned long *dst_addr, int size, 187 - unsigned long src_val, int asi); 188 189 - static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr, 190 - struct pt_regs *regs, int asi, int orig_asi) 191 { 192 unsigned long zero = 0; 193 unsigned long *src_val_p = &zero; ··· 219 break; 220 }; 221 } 222 - __do_int_store(dst_addr, size, src_val, asi); 223 } 224 225 static inline void advance(struct pt_regs *regs) ··· 242 return !floating_point_load_or_store_p(insn); 243 } 244 245 - void kernel_mna_trap_fault(void) 246 { 247 struct pt_regs *regs = current_thread_info()->kern_una_regs; 248 unsigned int insn = current_thread_info()->kern_una_insn; ··· 294 kernel_mna_trap_fault(); 295 } else { 296 unsigned long addr, *reg_addr; 297 - int orig_asi, asi; 298 299 addr = compute_effective_address(regs, insn, 300 ((insn >> 25) & 0x1f)); ··· 319 switch (dir) { 320 case load: 321 reg_addr = fetch_reg_addr(((insn>>25)&0x1f), regs); 322 - do_int_load(reg_addr, size, (unsigned long *) addr, 323 - decode_signedness(insn), asi); 324 - if (unlikely(asi != orig_asi)) { 325 unsigned long val_in = *reg_addr; 326 switch (size) { 327 case 2: ··· 344 break; 345 346 case store: 347 - do_int_store(((insn>>25)&0x1f), size, 348 - (unsigned long *) addr, regs, 349 - asi, orig_asi); 350 break; 351 352 default: 353 panic("Impossible kernel unaligned trap."); 354 /* Not reached... */ 355 } 356 - advance(regs); 357 } 358 } 359
··· 180 die_if_kernel(str, regs); 181 } 182 183 + extern int do_int_load(unsigned long *dest_reg, int size, 184 + unsigned long *saddr, int is_signed, int asi); 185 186 + extern int __do_int_store(unsigned long *dst_addr, int size, 187 + unsigned long src_val, int asi); 188 189 + static inline int do_int_store(int reg_num, int size, unsigned long *dst_addr, 190 + struct pt_regs *regs, int asi, int orig_asi) 191 { 192 unsigned long zero = 0; 193 unsigned long *src_val_p = &zero; ··· 219 break; 220 }; 221 } 222 + return __do_int_store(dst_addr, size, src_val, asi); 223 } 224 225 static inline void advance(struct pt_regs *regs) ··· 242 return !floating_point_load_or_store_p(insn); 243 } 244 245 + static void kernel_mna_trap_fault(void) 246 { 247 struct pt_regs *regs = current_thread_info()->kern_una_regs; 248 unsigned int insn = current_thread_info()->kern_una_insn; ··· 294 kernel_mna_trap_fault(); 295 } else { 296 unsigned long addr, *reg_addr; 297 + int orig_asi, asi, err; 298 299 addr = compute_effective_address(regs, insn, 300 ((insn >> 25) & 0x1f)); ··· 319 switch (dir) { 320 case load: 321 reg_addr = fetch_reg_addr(((insn>>25)&0x1f), regs); 322 + err = do_int_load(reg_addr, size, 323 + (unsigned long *) addr, 324 + decode_signedness(insn), asi); 325 + if (likely(!err) && unlikely(asi != orig_asi)) { 326 unsigned long val_in = *reg_addr; 327 switch (size) { 328 case 2: ··· 343 break; 344 345 case store: 346 + err = do_int_store(((insn>>25)&0x1f), size, 347 + (unsigned long *) addr, regs, 348 + asi, orig_asi); 349 break; 350 351 default: 352 panic("Impossible kernel unaligned trap."); 353 /* Not reached... */ 354 } 355 + if (unlikely(err)) 356 + kernel_mna_trap_fault(); 357 + else 358 + advance(regs); 359 } 360 } 361
+6 -10
arch/sparc64/lib/strncpy_from_user.S
··· 125 add %o2, %o3, %o0 126 .size __strncpy_from_user, .-__strncpy_from_user 127 128 - .section .fixup,#alloc,#execinstr 129 - .align 4 130 - 4: retl 131 - mov -EFAULT, %o0 132 - 133 .section __ex_table,#alloc 134 .align 4 135 - .word 60b, 4b 136 - .word 61b, 4b 137 - .word 62b, 4b 138 - .word 63b, 4b 139 - .word 64b, 4b
··· 125 add %o2, %o3, %o0 126 .size __strncpy_from_user, .-__strncpy_from_user 127 128 .section __ex_table,#alloc 129 .align 4 130 + .word 60b, __retl_efault 131 + .word 61b, __retl_efault 132 + .word 62b, __retl_efault 133 + .word 63b, __retl_efault 134 + .word 64b, __retl_efault 135 + .previous
+1
include/asm-sparc64/uaccess.h
··· 77 }; 78 79 extern void __ret_efault(void); 80 81 /* Uh, these should become the main single-value transfer routines.. 82 * They automatically use the right size if we just have the right
··· 77 }; 78 79 extern void __ret_efault(void); 80 + extern void __retl_efault(void); 81 82 /* Uh, these should become the main single-value transfer routines.. 83 * They automatically use the right size if we just have the right