• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Helper functions for trap handlers
4  *
5  * Copyright (C) 2000-2007, Axis Communications AB.
6  *
7  * Authors:   Bjorn Wesen
8  *            Hans-Peter Nilsson
9  *
10  */
11 
12 #include <linux/ptrace.h>
13 #include <linux/uaccess.h>
14 #include <linux/sched/debug.h>
15 
16 #include <arch/sv_addr_ag.h>
17 #include <arch/system.h>
18 
19 void
show_registers(struct pt_regs * regs)20 show_registers(struct pt_regs *regs)
21 {
22 	/*
23 	 * It's possible to use either the USP register or current->thread.usp.
24 	 * USP might not correspond to the current process for all cases this
25 	 * function is called, and current->thread.usp isn't up to date for the
26 	 * current process. Experience shows that using USP is the way to go.
27 	 */
28 	unsigned long usp = rdusp();
29 
30 	printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
31 	       regs->irp, regs->srp, regs->dccr, usp, regs->mof);
32 
33 	printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
34 	       regs->r0, regs->r1, regs->r2, regs->r3);
35 
36 	printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
37 	       regs->r4, regs->r5, regs->r6, regs->r7);
38 
39 	printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
40 	       regs->r8, regs->r9, regs->r10, regs->r11);
41 
42 	printk("r12: %08lx r13: %08lx oR10: %08lx  sp: %08lx\n",
43 	       regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs);
44 
45 	printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
46 
47 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
48 	       current->comm, current->pid, (unsigned long)current);
49 
50 	/*
51 	 * When in-kernel, we also print out the stack and code at the
52 	 * time of the fault..
53 	 */
54 	if (!user_mode(regs)) {
55 		int i;
56 
57 		show_stack(NULL, (unsigned long *)usp);
58 
59 		/*
60 		 * If the previous stack-dump wasn't a kernel one, dump the
61 		 * kernel stack now.
62 		 */
63 		if (usp != 0)
64 			show_stack(NULL, NULL);
65 
66 		printk("\nCode: ");
67 
68 		if (regs->irp < PAGE_OFFSET)
69 			goto bad_value;
70 
71 		/*
72 		 * Quite often the value at regs->irp doesn't point to the
73 		 * interesting instruction, which often is the previous
74 		 * instruction. So dump at an offset large enough that the
75 		 * instruction decoding should be in sync at the interesting
76 		 * point, but small enough to fit on a row. The regs->irp
77 		 * location is pointed out in a ksymoops-friendly way by
78 		 * wrapping the byte for that address in parenthesises.
79 		 */
80 		for (i = -12; i < 12; i++) {
81 			unsigned char c;
82 
83 			if (__get_user(c, &((unsigned char *)regs->irp)[i])) {
84 bad_value:
85 				printk(" Bad IP value.");
86 				break;
87 			}
88 
89 			if (i == 0)
90 				printk("(%02x) ", c);
91 			else
92 				printk("%02x ", c);
93 		}
94 		printk("\n");
95 	}
96 }
97 
98 void
arch_enable_nmi(void)99 arch_enable_nmi(void)
100 {
101 	asm volatile ("setf m");
102 }
103 
104 extern void (*nmi_handler)(struct pt_regs *);
handle_nmi(struct pt_regs * regs)105 void handle_nmi(struct pt_regs *regs)
106 {
107 	if (nmi_handler)
108 		nmi_handler(regs);
109 
110 	/* Wait until nmi is no longer active. (We enable NMI immediately after
111 	   returning from this function, and we don't want it happening while
112 	   exiting from the NMI interrupt handler.) */
113 	while (*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active))
114 		;
115 }
116 
117 #ifdef CONFIG_DEBUG_BUGVERBOSE
118 void
handle_BUG(struct pt_regs * regs)119 handle_BUG(struct pt_regs *regs)
120 {
121 	struct bug_frame f;
122 	unsigned char c;
123 	unsigned long irp = regs->irp;
124 
125 	if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f))
126 		return;
127 	if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
128 		return;
129 	if (__get_user(c, f.filename))
130 		f.filename = "<bad filename>";
131 
132 	printk("kernel BUG at %s:%d!\n", f.filename, f.line);
133 }
134 #endif
135