.. | .. |
---|
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 | /* |
---|