Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARC: Remove explicit passing around of ECR

With ECR now part of pt_regs

* No need to propagate from lowest asm handlers as arg
* No need to save it in tsk->thread.cause_code
* Avoid bit chopping to access the bit-fields

More code consolidation, cleanup

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>

+59 -78
+2 -3
arch/arc/include/asm/bug.h
··· 18 18 void show_regs(struct pt_regs *regs); 19 19 void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs); 20 20 void show_kernel_fault_diag(const char *str, struct pt_regs *regs, 21 - unsigned long address, unsigned long cause_reg); 22 - void die(const char *str, struct pt_regs *regs, unsigned long address, 23 - unsigned long cause_reg); 21 + unsigned long address); 22 + void die(const char *str, struct pt_regs *regs, unsigned long address); 24 23 25 24 #define BUG() do { \ 26 25 dump_stack(); \
+2 -2
arch/arc/include/asm/kgdb.h
··· 31 31 __asm__ __volatile__ ("trap_s 0x4\n"); 32 32 } 33 33 34 - extern void kgdb_trap(struct pt_regs *regs, int param); 34 + extern void kgdb_trap(struct pt_regs *regs); 35 35 36 36 enum arc700_linux_regnums { 37 37 _R0 = 0, ··· 53 53 }; 54 54 55 55 #else 56 - #define kgdb_trap(regs, param) 56 + #define kgdb_trap(regs) 57 57 #endif 58 58 59 59 #endif /* __ARC_KGDB_H__ */
+2 -4
arch/arc/include/asm/kprobes.h
··· 50 50 51 51 int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause); 52 52 void kretprobe_trampoline(void); 53 - void trap_is_kprobe(unsigned long cause, unsigned long address, 54 - struct pt_regs *regs); 53 + void trap_is_kprobe(unsigned long address, struct pt_regs *regs); 55 54 #else 56 - static void trap_is_kprobe(unsigned long cause, unsigned long address, 57 - struct pt_regs *regs) 55 + static void trap_is_kprobe(unsigned long address, struct pt_regs *regs) 58 56 { 59 57 } 60 58 #endif
-1
arch/arc/include/asm/processor.h
··· 29 29 unsigned long ksp; /* kernel mode stack pointer */ 30 30 unsigned long callee_reg; /* pointer to callee regs */ 31 31 unsigned long fault_address; /* dbls as brkpt holder as well */ 32 - unsigned long cause_code; /* Exception Cause Code (ECR) */ 33 32 #ifdef CONFIG_ARC_FPU_SAVE_RESTORE 34 33 struct arc_fpu fpu; 35 34 #endif
+2 -2
arch/arc/include/asm/unaligned.h
··· 16 16 17 17 #ifdef CONFIG_ARC_MISALIGN_ACCESS 18 18 int misaligned_fixup(unsigned long address, struct pt_regs *regs, 19 - unsigned long cause, struct callee_regs *cregs); 19 + struct callee_regs *cregs); 20 20 #else 21 21 static inline int 22 22 misaligned_fixup(unsigned long address, struct pt_regs *regs, 23 - unsigned long cause, struct callee_regs *cregs) 23 + struct callee_regs *cregs) 24 24 { 25 25 return 0; 26 26 }
+17 -23
arch/arc/kernel/entry.S
··· 274 274 SWITCH_TO_KERNEL_STK 275 275 SAVE_ALL_SYS 276 276 277 - lr r0, [ecr] 278 - lr r1, [efa] 279 - 280 - mov r2, sp 277 + lr r0, [efa] 278 + mov r1, sp 281 279 282 280 FAKE_RET_FROM_EXCPN r9 283 281 ··· 296 298 SWITCH_TO_KERNEL_STK 297 299 SAVE_ALL_SYS 298 300 299 - lr r0, [ecr] 300 - lr r1, [efa] 301 - mov r2, sp 301 + lr r0, [efa] 302 + mov r1, sp 302 303 bl do_memory_error 303 304 b ret_from_exception 304 305 ARC_EXIT mem_service ··· 314 317 SWITCH_TO_KERNEL_STK 315 318 SAVE_ALL_SYS 316 319 317 - lr r0, [ecr] 318 - lr r1, [efa] 319 - mov r2, sp 320 + lr r2, [ecr] 321 + lr r0, [efa] 322 + mov r1, sp 320 323 321 - lsr r3, r0, 8 324 + lsr r3, r2, 8 322 325 bmsk r3, r3, 7 323 326 brne r3, ECR_C_MCHK_DUP_TLB, 1f 324 327 ··· 381 384 382 385 ;========== (6b) Non aligned access ============ 383 386 4: 384 - mov r0, r2 ; cause code 385 - mov r2, sp ; pt_regs 387 + mov r0, r1 388 + mov r1, sp ; pt_regs 386 389 387 390 #ifdef CONFIG_ARC_MISALIGN_ACCESS 388 391 SAVE_CALLEE_SAVED_USER 389 - mov r3, sp ; callee_regs 392 + mov r2, sp ; callee_regs 390 393 391 394 bl do_misaligned_access 392 395 ··· 413 416 SWITCH_TO_KERNEL_STK 414 417 SAVE_ALL_SYS 415 418 416 - lr r0, [ecr] 417 - lr r1, [efa] 418 - mov r2, sp 419 + lr r0, [efa] 420 + mov r1, sp 419 421 420 422 FAKE_RET_FROM_EXCPN r9 421 423 ··· 433 437 SWITCH_TO_KERNEL_STK 434 438 SAVE_ALL_SYS 435 439 436 - lr r0, [ecr] 437 - lr r1, [efa] 438 - mov r2, sp 440 + lr r0, [efa] 441 + mov r1, sp 439 442 bl do_extension_fault 440 443 b ret_from_exception 441 444 ARC_EXIT EV_Extension ··· 490 495 trap_with_param: 491 496 492 497 ; stop_pc info by gdb needs this info 493 - mov r0, r12 494 - lr r1, [efa] 495 - mov r2, sp 498 + lr r0, [efa] 499 + mov r1, sp 496 500 497 501 ; Now that we have read EFA, its safe to do "fake" rtie 498 502 ; and get out of CPU exception mode
+1 -1
arch/arc/kernel/kgdb.c
··· 169 169 return 0; 170 170 } 171 171 172 - void kgdb_trap(struct pt_regs *regs, int param) 172 + void kgdb_trap(struct pt_regs *regs) 173 173 { 174 174 /* trap_s 3 is used for breakpoints that overwrite existing 175 175 * instructions, while trap_s 4 is used for compiled breakpoints.
+2 -3
arch/arc/kernel/kprobes.c
··· 517 517 return 0; 518 518 } 519 519 520 - void trap_is_kprobe(unsigned long cause, unsigned long address, 521 - struct pt_regs *regs) 520 + void trap_is_kprobe(unsigned long address, struct pt_regs *regs) 522 521 { 523 - notify_die(DIE_TRAP, "kprobe_trap", regs, address, cause, SIGTRAP); 522 + notify_die(DIE_TRAP, "kprobe_trap", regs, address, 0, SIGTRAP); 524 523 }
+24 -28
arch/arc/kernel/traps.c
··· 28 28 return; 29 29 } 30 30 31 - void die(const char *str, struct pt_regs *regs, unsigned long address, 32 - unsigned long cause_reg) 31 + void die(const char *str, struct pt_regs *regs, unsigned long address) 33 32 { 34 - show_kernel_fault_diag(str, regs, address, cause_reg); 33 + show_kernel_fault_diag(str, regs, address); 35 34 36 35 /* DEAD END */ 37 36 __asm__("flag 1"); ··· 41 42 * -for user faults enqueues requested signal 42 43 * -for kernel, chk if due to copy_(to|from)_user, otherwise die() 43 44 */ 44 - static noinline int handle_exception(unsigned long cause, char *str, 45 - struct pt_regs *regs, siginfo_t *info) 45 + static noinline int 46 + handle_exception(const char *str, struct pt_regs *regs, siginfo_t *info) 46 47 { 47 48 if (user_mode(regs)) { 48 49 struct task_struct *tsk = current; 49 50 50 51 tsk->thread.fault_address = (__force unsigned int)info->si_addr; 51 - tsk->thread.cause_code = cause; 52 52 53 53 force_sig_info(info->si_signo, info, tsk); 54 54 ··· 56 58 if (fixup_exception(regs)) 57 59 return 0; 58 60 59 - die(str, regs, (unsigned long)info->si_addr, cause); 61 + die(str, regs, (unsigned long)info->si_addr); 60 62 } 61 63 62 64 return 1; 63 65 } 64 66 65 67 #define DO_ERROR_INFO(signr, str, name, sicode) \ 66 - int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \ 68 + int name(unsigned long address, struct pt_regs *regs) \ 67 69 { \ 68 70 siginfo_t info = { \ 69 71 .si_signo = signr, \ ··· 71 73 .si_code = sicode, \ 72 74 .si_addr = (void __user *)address, \ 73 75 }; \ 74 - return handle_exception(cause, str, regs, &info);\ 76 + return handle_exception(str, regs, &info);\ 75 77 } 76 78 77 79 /* ··· 88 90 /* 89 91 * Entry Point for Misaligned Data access Exception, for emulating in software 90 92 */ 91 - int do_misaligned_access(unsigned long cause, unsigned long address, 92 - struct pt_regs *regs, struct callee_regs *cregs) 93 + int do_misaligned_access(unsigned long address, struct pt_regs *regs, 94 + struct callee_regs *cregs) 93 95 { 94 - if (misaligned_fixup(address, regs, cause, cregs) != 0) 95 - return do_misaligned_error(cause, address, regs); 96 + if (misaligned_fixup(address, regs, cregs) != 0) 97 + return do_misaligned_error(address, regs); 96 98 97 99 return 0; 98 100 } ··· 102 104 * Entry point for miscll errors such as Nested Exceptions 103 105 * -Duplicate TLB entry is handled seperately though 104 106 */ 105 - void do_machine_check_fault(unsigned long cause, unsigned long address, 106 - struct pt_regs *regs) 107 + void do_machine_check_fault(unsigned long address, struct pt_regs *regs) 107 108 { 108 - die("Machine Check Exception", regs, address, cause); 109 + die("Machine Check Exception", regs, address); 109 110 } 110 111 111 112 ··· 117 120 * -1 used for software breakpointing (gdb) 118 121 * -2 used by kprobes 119 122 */ 120 - void do_non_swi_trap(unsigned long cause, unsigned long address, 121 - struct pt_regs *regs) 123 + void do_non_swi_trap(unsigned long address, struct pt_regs *regs) 122 124 { 123 - unsigned int param = cause & 0xff; 125 + unsigned int param = regs->ecr_param; 124 126 125 127 switch (param) { 126 128 case 1: 127 - trap_is_brkpt(cause, address, regs); 129 + trap_is_brkpt(address, regs); 128 130 break; 129 131 130 132 case 2: 131 - trap_is_kprobe(param, address, regs); 133 + trap_is_kprobe(address, regs); 132 134 break; 133 135 134 136 case 3: 135 137 case 4: 136 - kgdb_trap(regs, param); 138 + kgdb_trap(regs); 137 139 break; 138 140 139 141 default: ··· 145 149 * -For a corner case, ARC kprobes implementation resorts to using 146 150 * this exception, hence the check 147 151 */ 148 - void do_insterror_or_kprobe(unsigned long cause, 149 - unsigned long address, 150 - struct pt_regs *regs) 152 + void do_insterror_or_kprobe(unsigned long address, struct pt_regs *regs) 151 153 { 154 + int rc; 155 + 152 156 /* Check if this exception is caused by kprobes */ 153 - if (notify_die(DIE_IERR, "kprobe_ierr", regs, address, 154 - cause, SIGILL) == NOTIFY_STOP) 157 + rc = notify_die(DIE_IERR, "kprobe_ierr", regs, address, 0, SIGILL); 158 + if (rc == NOTIFY_STOP) 155 159 return; 156 160 157 - insterror_is_error(cause, address, regs); 161 + insterror_is_error(address, regs); 158 162 }
+1 -2
arch/arc/kernel/troubleshoot.c
··· 209 209 } 210 210 211 211 void show_kernel_fault_diag(const char *str, struct pt_regs *regs, 212 - unsigned long address, unsigned long cause_reg) 212 + unsigned long address) 213 213 { 214 214 current->thread.fault_address = address; 215 - current->thread.cause_code = cause_reg; 216 215 217 216 /* Caller and Callee regs */ 218 217 show_regs(regs);
+1 -1
arch/arc/kernel/unaligned.c
··· 187 187 * Returns 0 if successfully handled, 1 if some error happened 188 188 */ 189 189 int misaligned_fixup(unsigned long address, struct pt_regs *regs, 190 - unsigned long cause, struct callee_regs *cregs) 190 + struct callee_regs *cregs) 191 191 { 192 192 struct disasm_state state; 193 193 char buf[TASK_COMM_LEN];
+5 -7
arch/arc/mm/fault.c
··· 52 52 return 1; 53 53 } 54 54 55 - void do_page_fault(struct pt_regs *regs, unsigned long address, 56 - unsigned long cause_code) 55 + void do_page_fault(struct pt_regs *regs, unsigned long address) 57 56 { 58 57 struct vm_area_struct *vma = NULL; 59 58 struct task_struct *tsk = current; 60 59 struct mm_struct *mm = tsk->mm; 61 60 siginfo_t info; 62 61 int fault, ret; 63 - int write = cause_code & (1 << ECR_C_BIT_DTLB_ST_MISS); /* ST/EX */ 62 + int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */ 64 63 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 65 64 (write ? FAULT_FLAG_WRITE : 0); 66 65 ··· 110 111 111 112 /* Handle protection violation, execute on heap or stack */ 112 113 113 - if (cause_code == ((ECR_V_PROTV << 16) | ECR_C_PROTV_INST_FETCH)) 114 + if ((regs->ecr_vec == ECR_V_PROTV) && 115 + (regs->ecr_cause == ECR_C_PROTV_INST_FETCH)) 114 116 goto bad_area; 115 117 116 118 if (write) { ··· 178 178 /* User mode accesses just cause a SIGSEGV */ 179 179 if (user_mode(regs)) { 180 180 tsk->thread.fault_address = address; 181 - tsk->thread.cause_code = cause_code; 182 181 info.si_signo = SIGSEGV; 183 182 info.si_errno = 0; 184 183 /* info.si_code has been set above */ ··· 198 199 if (fixup_exception(regs)) 199 200 return; 200 201 201 - die("Oops", regs, address, cause_code); 202 + die("Oops", regs, address); 202 203 203 204 out_of_memory: 204 205 if (is_global_init(tsk)) { ··· 219 220 goto no_context; 220 221 221 222 tsk->thread.fault_address = address; 222 - tsk->thread.cause_code = cause_code; 223 223 info.si_signo = SIGBUS; 224 224 info.si_errno = 0; 225 225 info.si_code = BUS_ADRERR;
-1
arch/arc/mm/tlbex.S
··· 382 382 ; ------- setup args for Linux Page fault Hanlder --------- 383 383 mov_s r0, sp 384 384 lr r1, [efa] 385 - lr r2, [ecr] 386 385 387 386 ; We don't want exceptions to be disabled while the fault is handled. 388 387 ; Now that we have saved the context we return from exception hence