Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-microblaze.git] / arch / nds32 / kernel / traps.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
3
4 #include <linux/module.h>
5 #include <linux/personality.h>
6 #include <linux/kallsyms.h>
7 #include <linux/hardirq.h>
8 #include <linux/kdebug.h>
9 #include <linux/sched/task_stack.h>
10 #include <linux/uaccess.h>
11
12 #include <asm/proc-fns.h>
13 #include <asm/unistd.h>
14
15 #include <linux/ptrace.h>
16 #include <nds32_intrinsic.h>
17
18 extern void show_pte(struct mm_struct *mm, unsigned long addr);
19
20 /*
21  * Dump out the contents of some memory nicely...
22  */
23 void dump_mem(const char *lvl, unsigned long bottom, unsigned long top)
24 {
25         unsigned long first;
26         mm_segment_t fs;
27         int i;
28
29         /*
30          * We need to switch to kernel mode so that we can use __get_user
31          * to safely read from kernel space.  Note that we now dump the
32          * code first, just in case the backtrace kills us.
33          */
34         fs = get_fs();
35         set_fs(KERNEL_DS);
36
37         pr_emerg("%s(0x%08lx to 0x%08lx)\n", lvl, bottom, top);
38
39         for (first = bottom & ~31; first < top; first += 32) {
40                 unsigned long p;
41                 char str[sizeof(" 12345678") * 8 + 1];
42
43                 memset(str, ' ', sizeof(str));
44                 str[sizeof(str) - 1] = '\0';
45
46                 for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
47                         if (p >= bottom && p < top) {
48                                 unsigned long val;
49                                 if (__get_user(val, (unsigned long *)p) == 0)
50                                         sprintf(str + i * 9, " %08lx", val);
51                                 else
52                                         sprintf(str + i * 9, " ????????");
53                         }
54                 }
55                 pr_emerg("%s%04lx:%s\n", lvl, first & 0xffff, str);
56         }
57
58         set_fs(fs);
59 }
60
61 EXPORT_SYMBOL(dump_mem);
62
63 static void dump_instr(struct pt_regs *regs)
64 {
65         unsigned long addr = instruction_pointer(regs);
66         mm_segment_t fs;
67         char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
68         int i;
69
70         return;
71         /*
72          * We need to switch to kernel mode so that we can use __get_user
73          * to safely read from kernel space.  Note that we now dump the
74          * code first, just in case the backtrace kills us.
75          */
76         fs = get_fs();
77         set_fs(KERNEL_DS);
78
79         pr_emerg("Code: ");
80         for (i = -4; i < 1; i++) {
81                 unsigned int val, bad;
82
83                 bad = __get_user(val, &((u32 *) addr)[i]);
84
85                 if (!bad) {
86                         p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val);
87                 } else {
88                         p += sprintf(p, "bad PC value");
89                         break;
90                 }
91         }
92         pr_emerg("Code: %s\n", str);
93
94         set_fs(fs);
95 }
96
97 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
98 #include <linux/ftrace.h>
99 static void
100 get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
101 {
102         if (*addr == (unsigned long)return_to_handler) {
103                 int index = tsk->curr_ret_stack;
104
105                 if (tsk->ret_stack && index >= *graph) {
106                         index -= *graph;
107                         *addr = tsk->ret_stack[index].ret;
108                         (*graph)++;
109                 }
110         }
111 }
112 #else
113 static inline void
114 get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
115 {
116 }
117 #endif
118
119 #define LOOP_TIMES (100)
120 static void __dump(struct task_struct *tsk, unsigned long *base_reg)
121 {
122         unsigned long ret_addr;
123         int cnt = LOOP_TIMES, graph = 0;
124         pr_emerg("Call Trace:\n");
125         if (!IS_ENABLED(CONFIG_FRAME_POINTER)) {
126                 while (!kstack_end(base_reg)) {
127                         ret_addr = *base_reg++;
128                         if (__kernel_text_address(ret_addr)) {
129                                 get_real_ret_addr(&ret_addr, tsk, &graph);
130                                 print_ip_sym(ret_addr);
131                         }
132                         if (--cnt < 0)
133                                 break;
134                 }
135         } else {
136                 while (!kstack_end((void *)base_reg) &&
137                        !((unsigned long)base_reg & 0x3) &&
138                        ((unsigned long)base_reg >= TASK_SIZE)) {
139                         unsigned long next_fp;
140 #if !defined(NDS32_ABI_2)
141                         ret_addr = base_reg[0];
142                         next_fp = base_reg[1];
143 #else
144                         ret_addr = base_reg[-1];
145                         next_fp = base_reg[FP_OFFSET];
146 #endif
147                         if (__kernel_text_address(ret_addr)) {
148                                 get_real_ret_addr(&ret_addr, tsk, &graph);
149                                 print_ip_sym(ret_addr);
150                         }
151                         if (--cnt < 0)
152                                 break;
153                         base_reg = (unsigned long *)next_fp;
154                 }
155         }
156         pr_emerg("\n");
157 }
158
159 void show_stack(struct task_struct *tsk, unsigned long *sp)
160 {
161         unsigned long *base_reg;
162
163         if (!tsk)
164                 tsk = current;
165         if (!IS_ENABLED(CONFIG_FRAME_POINTER)) {
166                 if (tsk != current)
167                         base_reg = (unsigned long *)(tsk->thread.cpu_context.sp);
168                 else
169                         __asm__ __volatile__("\tori\t%0, $sp, #0\n":"=r"(base_reg));
170         } else {
171                 if (tsk != current)
172                         base_reg = (unsigned long *)(tsk->thread.cpu_context.fp);
173                 else
174                         __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(base_reg));
175         }
176         __dump(tsk, base_reg);
177         barrier();
178 }
179
180 DEFINE_SPINLOCK(die_lock);
181
182 /*
183  * This function is protected against re-entrancy.
184  */
185 void die(const char *str, struct pt_regs *regs, int err)
186 {
187         struct task_struct *tsk = current;
188         static int die_counter;
189
190         console_verbose();
191         spin_lock_irq(&die_lock);
192         bust_spinlocks(1);
193
194         pr_emerg("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
195         print_modules();
196         pr_emerg("CPU: %i\n", smp_processor_id());
197         show_regs(regs);
198         pr_emerg("Process %s (pid: %d, stack limit = 0x%p)\n",
199                  tsk->comm, tsk->pid, task_thread_info(tsk) + 1);
200
201         if (!user_mode(regs) || in_interrupt()) {
202                 dump_mem("Stack: ", regs->sp,
203                          THREAD_SIZE + (unsigned long)task_thread_info(tsk));
204                 dump_instr(regs);
205                 dump_stack();
206         }
207
208         bust_spinlocks(0);
209         spin_unlock_irq(&die_lock);
210         do_exit(SIGSEGV);
211 }
212
213 EXPORT_SYMBOL(die);
214
215 void die_if_kernel(const char *str, struct pt_regs *regs, int err)
216 {
217         if (user_mode(regs))
218                 return;
219
220         die(str, regs, err);
221 }
222
223 int bad_syscall(int n, struct pt_regs *regs)
224 {
225         if (current->personality != PER_LINUX) {
226                 send_sig(SIGSEGV, current, 1);
227                 return regs->uregs[0];
228         }
229
230         force_sig_fault(SIGILL, ILL_ILLTRP,
231                         (void __user *)instruction_pointer(regs) - 4, current);
232         die_if_kernel("Oops - bad syscall", regs, n);
233         return regs->uregs[0];
234 }
235
236 void __pte_error(const char *file, int line, unsigned long val)
237 {
238         pr_emerg("%s:%d: bad pte %08lx.\n", file, line, val);
239 }
240
241 void __pmd_error(const char *file, int line, unsigned long val)
242 {
243         pr_emerg("%s:%d: bad pmd %08lx.\n", file, line, val);
244 }
245
246 void __pgd_error(const char *file, int line, unsigned long val)
247 {
248         pr_emerg("%s:%d: bad pgd %08lx.\n", file, line, val);
249 }
250
251 extern char *exception_vector, *exception_vector_end;
252 void __init trap_init(void)
253 {
254         return;
255 }
256
257 void __init early_trap_init(void)
258 {
259         unsigned long ivb = 0;
260         unsigned long base = PAGE_OFFSET;
261
262         memcpy((unsigned long *)base, (unsigned long *)&exception_vector,
263                ((unsigned long)&exception_vector_end -
264                 (unsigned long)&exception_vector));
265         ivb = __nds32__mfsr(NDS32_SR_IVB);
266         /* Check platform support. */
267         if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) < 2)
268                 panic
269                     ("IVIC mode is not allowed on the platform with interrupt controller\n");
270         __nds32__mtsr((ivb & ~IVB_mskESZ) | (IVB_valESZ16 << IVB_offESZ) |
271                       IVB_BASE, NDS32_SR_IVB);
272         __nds32__mtsr(INT_MASK_INITAIAL_VAL, NDS32_SR_INT_MASK);
273
274         /*
275          * 0x800 = 128 vectors * 16byte.
276          * It should be enough to flush a page.
277          */
278         cpu_cache_wbinval_page(base, true);
279 }
280
281 void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
282                   int error_code, int si_code)
283 {
284         tsk->thread.trap_no = ENTRY_DEBUG_RELATED;
285         tsk->thread.error_code = error_code;
286
287         force_sig_fault(SIGTRAP, si_code,
288                         (void __user *)instruction_pointer(regs), tsk);
289 }
290
291 void do_debug_trap(unsigned long entry, unsigned long addr,
292                    unsigned long type, struct pt_regs *regs)
293 {
294         if (notify_die(DIE_OOPS, "Oops", regs, addr, type, SIGTRAP)
295             == NOTIFY_STOP)
296                 return;
297
298         if (user_mode(regs)) {
299                 /* trap_signal */
300                 send_sigtrap(current, regs, 0, TRAP_BRKPT);
301         } else {
302                 /* kernel_trap */
303                 if (!fixup_exception(regs))
304                         die("unexpected kernel_trap", regs, 0);
305         }
306 }
307
308 void unhandled_interruption(struct pt_regs *regs)
309 {
310         pr_emerg("unhandled_interruption\n");
311         show_regs(regs);
312         if (!user_mode(regs))
313                 do_exit(SIGKILL);
314         force_sig(SIGKILL, current);
315 }
316
317 void unhandled_exceptions(unsigned long entry, unsigned long addr,
318                           unsigned long type, struct pt_regs *regs)
319 {
320         pr_emerg("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry,
321                  addr, type);
322         show_regs(regs);
323         if (!user_mode(regs))
324                 do_exit(SIGKILL);
325         force_sig(SIGKILL, current);
326 }
327
328 extern int do_page_fault(unsigned long entry, unsigned long addr,
329                          unsigned int error_code, struct pt_regs *regs);
330
331 /*
332  * 2:DEF dispatch for TLB MISC exception handler
333 */
334
335 void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr,
336                           unsigned long type, struct pt_regs *regs)
337 {
338         type = type & (ITYPE_mskINST | ITYPE_mskETYPE);
339         if ((type & ITYPE_mskETYPE) < 5) {
340                 /* Permission exceptions */
341                 do_page_fault(entry, addr, type, regs);
342         } else
343                 unhandled_exceptions(entry, addr, type, regs);
344 }
345
346 void do_revinsn(struct pt_regs *regs)
347 {
348         pr_emerg("Reserved Instruction\n");
349         show_regs(regs);
350         if (!user_mode(regs))
351                 do_exit(SIGILL);
352         force_sig(SIGILL, current);
353 }
354
355 #ifdef CONFIG_ALIGNMENT_TRAP
356 extern int unalign_access_mode;
357 extern int do_unaligned_access(unsigned long addr, struct pt_regs *regs);
358 #endif
359 void do_dispatch_general(unsigned long entry, unsigned long addr,
360                          unsigned long itype, struct pt_regs *regs,
361                          unsigned long oipc)
362 {
363         unsigned int swid = itype >> ITYPE_offSWID;
364         unsigned long type = itype & (ITYPE_mskINST | ITYPE_mskETYPE);
365         if (type == ETYPE_ALIGNMENT_CHECK) {
366 #ifdef CONFIG_ALIGNMENT_TRAP
367                 /* Alignment check */
368                 if (user_mode(regs) && unalign_access_mode) {
369                         int ret;
370                         ret = do_unaligned_access(addr, regs);
371
372                         if (ret == 0)
373                                 return;
374
375                         if (ret == -EFAULT)
376                                 pr_emerg
377                                     ("Unhandled unaligned access exception\n");
378                 }
379 #endif
380                 do_page_fault(entry, addr, type, regs);
381         } else if (type == ETYPE_RESERVED_INSTRUCTION) {
382                 /* Reserved instruction */
383                 do_revinsn(regs);
384         } else if (type == ETYPE_TRAP && swid == SWID_RAISE_INTERRUPT_LEVEL) {
385                 /* trap, used on v3 EDM target debugging workaround */
386                 /*
387                  * DIPC(OIPC) is passed as parameter before
388                  * interrupt is enabled, so the DIPC will not be corrupted
389                  * even though interrupts are coming in
390                  */
391                 /*
392                  * 1. update ipc
393                  * 2. update pt_regs ipc with oipc
394                  * 3. update pt_regs ipsw (clear DEX)
395                  */
396                 __asm__ volatile ("mtsr %0, $IPC\n\t"::"r" (oipc));
397                 regs->ipc = oipc;
398                 if (regs->pipsw & PSW_mskDEX) {
399                         pr_emerg
400                             ("Nested Debug exception is possibly happened\n");
401                         pr_emerg("ipc:%08x pipc:%08x\n",
402                                  (unsigned int)regs->ipc,
403                                  (unsigned int)regs->pipc);
404                 }
405                 do_debug_trap(entry, addr, itype, regs);
406                 regs->ipsw &= ~PSW_mskDEX;
407         } else
408                 unhandled_exceptions(entry, addr, type, regs);
409 }