| .. | .. |
|---|
| 12 | 12 | |
|---|
| 13 | 13 | #include <asm/proc-fns.h> |
|---|
| 14 | 14 | #include <asm/unistd.h> |
|---|
| 15 | +#include <asm/fpu.h> |
|---|
| 15 | 16 | |
|---|
| 16 | 17 | #include <linux/ptrace.h> |
|---|
| 17 | 18 | #include <nds32_intrinsic.h> |
|---|
| .. | .. |
|---|
| 96 | 97 | } |
|---|
| 97 | 98 | |
|---|
| 98 | 99 | #define LOOP_TIMES (100) |
|---|
| 99 | | -static void __dump(struct task_struct *tsk, unsigned long *base_reg) |
|---|
| 100 | +static void __dump(struct task_struct *tsk, unsigned long *base_reg, |
|---|
| 101 | + const char *loglvl) |
|---|
| 100 | 102 | { |
|---|
| 101 | 103 | unsigned long ret_addr; |
|---|
| 102 | 104 | int cnt = LOOP_TIMES, graph = 0; |
|---|
| 103 | | - pr_emerg("Call Trace:\n"); |
|---|
| 105 | + printk("%sCall Trace:\n", loglvl); |
|---|
| 104 | 106 | if (!IS_ENABLED(CONFIG_FRAME_POINTER)) { |
|---|
| 105 | 107 | while (!kstack_end(base_reg)) { |
|---|
| 106 | 108 | ret_addr = *base_reg++; |
|---|
| 107 | 109 | if (__kernel_text_address(ret_addr)) { |
|---|
| 108 | 110 | ret_addr = ftrace_graph_ret_addr( |
|---|
| 109 | 111 | tsk, &graph, ret_addr, NULL); |
|---|
| 110 | | - print_ip_sym(ret_addr); |
|---|
| 112 | + print_ip_sym(loglvl, ret_addr); |
|---|
| 111 | 113 | } |
|---|
| 112 | 114 | if (--cnt < 0) |
|---|
| 113 | 115 | break; |
|---|
| .. | .. |
|---|
| 123 | 125 | |
|---|
| 124 | 126 | ret_addr = ftrace_graph_ret_addr( |
|---|
| 125 | 127 | tsk, &graph, ret_addr, NULL); |
|---|
| 126 | | - print_ip_sym(ret_addr); |
|---|
| 128 | + print_ip_sym(loglvl, ret_addr); |
|---|
| 127 | 129 | } |
|---|
| 128 | 130 | if (--cnt < 0) |
|---|
| 129 | 131 | break; |
|---|
| 130 | 132 | base_reg = (unsigned long *)next_fp; |
|---|
| 131 | 133 | } |
|---|
| 132 | 134 | } |
|---|
| 133 | | - pr_emerg("\n"); |
|---|
| 135 | + printk("%s\n", loglvl); |
|---|
| 134 | 136 | } |
|---|
| 135 | 137 | |
|---|
| 136 | | -void show_stack(struct task_struct *tsk, unsigned long *sp) |
|---|
| 138 | +void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) |
|---|
| 137 | 139 | { |
|---|
| 138 | 140 | unsigned long *base_reg; |
|---|
| 139 | 141 | |
|---|
| .. | .. |
|---|
| 150 | 152 | else |
|---|
| 151 | 153 | __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(base_reg)); |
|---|
| 152 | 154 | } |
|---|
| 153 | | - __dump(tsk, base_reg); |
|---|
| 155 | + __dump(tsk, base_reg, loglvl); |
|---|
| 154 | 156 | barrier(); |
|---|
| 155 | 157 | } |
|---|
| 156 | 158 | |
|---|
| .. | .. |
|---|
| 183 | 185 | |
|---|
| 184 | 186 | bust_spinlocks(0); |
|---|
| 185 | 187 | spin_unlock_irq(&die_lock); |
|---|
| 186 | | - do_exit(SIGSEGV); |
|---|
| 188 | + make_task_dead(SIGSEGV); |
|---|
| 187 | 189 | } |
|---|
| 188 | 190 | |
|---|
| 189 | 191 | EXPORT_SYMBOL(die); |
|---|
| .. | .. |
|---|
| 204 | 206 | } |
|---|
| 205 | 207 | |
|---|
| 206 | 208 | force_sig_fault(SIGILL, ILL_ILLTRP, |
|---|
| 207 | | - (void __user *)instruction_pointer(regs) - 4, current); |
|---|
| 209 | + (void __user *)instruction_pointer(regs) - 4); |
|---|
| 208 | 210 | die_if_kernel("Oops - bad syscall", regs, n); |
|---|
| 209 | 211 | return regs->uregs[0]; |
|---|
| 210 | 212 | } |
|---|
| .. | .. |
|---|
| 254 | 256 | cpu_cache_wbinval_page(base, true); |
|---|
| 255 | 257 | } |
|---|
| 256 | 258 | |
|---|
| 257 | | -void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, |
|---|
| 258 | | - int error_code, int si_code) |
|---|
| 259 | +static void send_sigtrap(struct pt_regs *regs, int error_code, int si_code) |
|---|
| 259 | 260 | { |
|---|
| 261 | + struct task_struct *tsk = current; |
|---|
| 262 | + |
|---|
| 260 | 263 | tsk->thread.trap_no = ENTRY_DEBUG_RELATED; |
|---|
| 261 | 264 | tsk->thread.error_code = error_code; |
|---|
| 262 | 265 | |
|---|
| 263 | 266 | force_sig_fault(SIGTRAP, si_code, |
|---|
| 264 | | - (void __user *)instruction_pointer(regs), tsk); |
|---|
| 267 | + (void __user *)instruction_pointer(regs)); |
|---|
| 265 | 268 | } |
|---|
| 266 | 269 | |
|---|
| 267 | 270 | void do_debug_trap(unsigned long entry, unsigned long addr, |
|---|
| .. | .. |
|---|
| 273 | 276 | |
|---|
| 274 | 277 | if (user_mode(regs)) { |
|---|
| 275 | 278 | /* trap_signal */ |
|---|
| 276 | | - send_sigtrap(current, regs, 0, TRAP_BRKPT); |
|---|
| 279 | + send_sigtrap(regs, 0, TRAP_BRKPT); |
|---|
| 277 | 280 | } else { |
|---|
| 278 | 281 | /* kernel_trap */ |
|---|
| 279 | 282 | if (!fixup_exception(regs)) |
|---|
| .. | .. |
|---|
| 286 | 289 | pr_emerg("unhandled_interruption\n"); |
|---|
| 287 | 290 | show_regs(regs); |
|---|
| 288 | 291 | if (!user_mode(regs)) |
|---|
| 289 | | - do_exit(SIGKILL); |
|---|
| 290 | | - force_sig(SIGKILL, current); |
|---|
| 292 | + make_task_dead(SIGKILL); |
|---|
| 293 | + force_sig(SIGKILL); |
|---|
| 291 | 294 | } |
|---|
| 292 | 295 | |
|---|
| 293 | 296 | void unhandled_exceptions(unsigned long entry, unsigned long addr, |
|---|
| .. | .. |
|---|
| 297 | 300 | addr, type); |
|---|
| 298 | 301 | show_regs(regs); |
|---|
| 299 | 302 | if (!user_mode(regs)) |
|---|
| 300 | | - do_exit(SIGKILL); |
|---|
| 301 | | - force_sig(SIGKILL, current); |
|---|
| 303 | + make_task_dead(SIGKILL); |
|---|
| 304 | + force_sig(SIGKILL); |
|---|
| 302 | 305 | } |
|---|
| 303 | 306 | |
|---|
| 304 | 307 | extern int do_page_fault(unsigned long entry, unsigned long addr, |
|---|
| .. | .. |
|---|
| 324 | 327 | pr_emerg("Reserved Instruction\n"); |
|---|
| 325 | 328 | show_regs(regs); |
|---|
| 326 | 329 | if (!user_mode(regs)) |
|---|
| 327 | | - do_exit(SIGILL); |
|---|
| 328 | | - force_sig(SIGILL, current); |
|---|
| 330 | + make_task_dead(SIGILL); |
|---|
| 331 | + force_sig(SIGILL); |
|---|
| 329 | 332 | } |
|---|
| 330 | 333 | |
|---|
| 331 | 334 | #ifdef CONFIG_ALIGNMENT_TRAP |
|---|
| .. | .. |
|---|
| 357 | 360 | } else if (type == ETYPE_RESERVED_INSTRUCTION) { |
|---|
| 358 | 361 | /* Reserved instruction */ |
|---|
| 359 | 362 | do_revinsn(regs); |
|---|
| 363 | + } else if (type == ETYPE_COPROCESSOR) { |
|---|
| 364 | + /* Coprocessor */ |
|---|
| 365 | +#if IS_ENABLED(CONFIG_FPU) |
|---|
| 366 | + unsigned int fucop_exist = __nds32__mfsr(NDS32_SR_FUCOP_EXIST); |
|---|
| 367 | + unsigned int cpid = ((itype & ITYPE_mskCPID) >> ITYPE_offCPID); |
|---|
| 368 | + |
|---|
| 369 | + if ((cpid == FPU_CPID) && |
|---|
| 370 | + (fucop_exist & FUCOP_EXIST_mskCP0ISFPU)) { |
|---|
| 371 | + unsigned int subtype = (itype & ITYPE_mskSTYPE); |
|---|
| 372 | + |
|---|
| 373 | + if (true == do_fpu_exception(subtype, regs)) |
|---|
| 374 | + return; |
|---|
| 375 | + } |
|---|
| 376 | +#endif |
|---|
| 377 | + unhandled_exceptions(entry, addr, type, regs); |
|---|
| 360 | 378 | } else if (type == ETYPE_TRAP && swid == SWID_RAISE_INTERRUPT_LEVEL) { |
|---|
| 361 | 379 | /* trap, used on v3 EDM target debugging workaround */ |
|---|
| 362 | 380 | /* |
|---|