1  // SPDX-License-Identifier: GPL-2.0
2  #include <linux/bug.h>
3  #include <linux/io.h>
4  #include <linux/types.h>
5  #include <linux/kdebug.h>
6  #include <linux/signal.h>
7  #include <linux/sched.h>
8  #include <linux/sched/debug.h>
9  #include <linux/sched/task_stack.h>
10  #include <linux/uaccess.h>
11  #include <linux/hardirq.h>
12  #include <linux/kernel.h>
13  #include <linux/kexec.h>
14  #include <linux/sched/signal.h>
15  
16  #include <linux/extable.h>
17  #include <linux/module.h>	/* print_modules */
18  
19  #include <asm/ftrace.h>
20  #include <asm/unwinder.h>
21  #include <asm/traps.h>
22  
23  static DEFINE_SPINLOCK(die_lock);
24  
die(const char * str,struct pt_regs * regs,long err)25  void __noreturn die(const char *str, struct pt_regs *regs, long err)
26  {
27  	static int die_counter;
28  
29  	oops_enter();
30  
31  	spin_lock_irq(&die_lock);
32  	console_verbose();
33  	bust_spinlocks(1);
34  
35  	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
36  	print_modules();
37  	show_regs(regs);
38  
39  	printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
40  			task_pid_nr(current), task_stack_page(current) + 1);
41  
42  	if (!user_mode(regs) || in_interrupt())
43  		dump_mem("Stack: ", KERN_DEFAULT, regs->regs[15],
44  			THREAD_SIZE + (unsigned long)task_stack_page(current));
45  
46  	notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV);
47  
48  	bust_spinlocks(0);
49  	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
50  	spin_unlock_irq(&die_lock);
51  	oops_exit();
52  
53  	if (kexec_should_crash(current))
54  		crash_kexec(regs);
55  
56  	if (in_interrupt())
57  		panic("Fatal exception in interrupt");
58  
59  	if (panic_on_oops)
60  		panic("Fatal exception");
61  
62  	make_task_dead(SIGSEGV);
63  }
64  
die_if_kernel(const char * str,struct pt_regs * regs,long err)65  void die_if_kernel(const char *str, struct pt_regs *regs, long err)
66  {
67  	if (!user_mode(regs))
68  		die(str, regs, err);
69  }
70  
71  /*
72   * try and fix up kernelspace address errors
73   * - userspace errors just cause EFAULT to be returned, resulting in SEGV
74   * - kernel/userspace interfaces cause a jump to an appropriate handler
75   * - other kernel errors are bad
76   */
die_if_no_fixup(const char * str,struct pt_regs * regs,long err)77  void die_if_no_fixup(const char *str, struct pt_regs *regs, long err)
78  {
79  	if (!user_mode(regs)) {
80  		const struct exception_table_entry *fixup;
81  		fixup = search_exception_tables(regs->pc);
82  		if (fixup) {
83  			regs->pc = fixup->fixup;
84  			return;
85  		}
86  
87  		die(str, regs, err);
88  	}
89  }
90  
91  #ifdef CONFIG_GENERIC_BUG
handle_BUG(struct pt_regs * regs)92  static void handle_BUG(struct pt_regs *regs)
93  {
94  	const struct bug_entry *bug;
95  	unsigned long bugaddr = regs->pc;
96  	enum bug_trap_type tt;
97  
98  	if (!is_valid_bugaddr(bugaddr))
99  		goto invalid;
100  
101  	bug = find_bug(bugaddr);
102  
103  	/* Switch unwinders when unwind_stack() is called */
104  	if (bug->flags & BUGFLAG_UNWINDER)
105  		unwinder_faulted = 1;
106  
107  	tt = report_bug(bugaddr, regs);
108  	if (tt == BUG_TRAP_TYPE_WARN) {
109  		regs->pc += instruction_size(bugaddr);
110  		return;
111  	}
112  
113  invalid:
114  	die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
115  }
116  
is_valid_bugaddr(unsigned long addr)117  int is_valid_bugaddr(unsigned long addr)
118  {
119  	insn_size_t opcode;
120  
121  	if (addr < PAGE_OFFSET)
122  		return 0;
123  	if (get_kernel_nofault(opcode, (insn_size_t *)addr))
124  		return 0;
125  	if (opcode == TRAPA_BUG_OPCODE)
126  		return 1;
127  
128  	return 0;
129  }
130  #endif
131  
132  /*
133   * Generic trap handler.
134   */
BUILD_TRAP_HANDLER(debug)135  BUILD_TRAP_HANDLER(debug)
136  {
137  	TRAP_HANDLER_DECL;
138  
139  	/* Rewind */
140  	regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
141  
142  	if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff,
143  		       SIGTRAP) == NOTIFY_STOP)
144  		return;
145  
146  	force_sig(SIGTRAP);
147  }
148  
149  /*
150   * Special handler for BUG() traps.
151   */
BUILD_TRAP_HANDLER(bug)152  BUILD_TRAP_HANDLER(bug)
153  {
154  	TRAP_HANDLER_DECL;
155  
156  	/* Rewind */
157  	regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
158  
159  	if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
160  		       SIGTRAP) == NOTIFY_STOP)
161  		return;
162  
163  #ifdef CONFIG_GENERIC_BUG
164  	if (__kernel_text_address(instruction_pointer(regs))) {
165  		insn_size_t insn = *(insn_size_t *)instruction_pointer(regs);
166  		if (insn == TRAPA_BUG_OPCODE)
167  			handle_BUG(regs);
168  		return;
169  	}
170  #endif
171  
172  	force_sig(SIGTRAP);
173  }
174  
BUILD_TRAP_HANDLER(nmi)175  BUILD_TRAP_HANDLER(nmi)
176  {
177  	TRAP_HANDLER_DECL;
178  
179  	arch_ftrace_nmi_enter();
180  
181  	nmi_enter();
182  	this_cpu_inc(irq_stat.__nmi_count);
183  
184  	switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
185  	case NOTIFY_OK:
186  	case NOTIFY_STOP:
187  		break;
188  	case NOTIFY_BAD:
189  		die("Fatal Non-Maskable Interrupt", regs, SIGINT);
190  	default:
191  		printk(KERN_ALERT "Got NMI, but nobody cared. Ignoring...\n");
192  		break;
193  	}
194  
195  	nmi_exit();
196  
197  	arch_ftrace_nmi_exit();
198  }
199