1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
25a4f7c66SPaul Mundt #include <linux/bug.h>
35a4f7c66SPaul Mundt #include <linux/io.h>
45a4f7c66SPaul Mundt #include <linux/types.h>
55a4f7c66SPaul Mundt #include <linux/kdebug.h>
647a3eb95SPaul Mundt #include <linux/signal.h>
747a3eb95SPaul Mundt #include <linux/sched.h>
8b17b0153SIngo Molnar #include <linux/sched/debug.h>
968db0cf1SIngo Molnar #include <linux/sched/task_stack.h>
109a33fc21SPaul Mundt #include <linux/uaccess.h>
111e1030dcSPaul Mundt #include <linux/hardirq.h>
125f857bceSPaul Mundt #include <linux/kernel.h>
135f857bceSPaul Mundt #include <linux/kexec.h>
143f07c014SIngo Molnar #include <linux/sched/signal.h>
153f07c014SIngo Molnar
16d92280d1SPaul Gortmaker #include <linux/extable.h>
17d92280d1SPaul Gortmaker #include <linux/module.h> /* print_modules */
18e115f2c1SPaul Mundt #include <asm/unwinder.h>
19e839ca52SDavid Howells #include <asm/traps.h>
205a4f7c66SPaul Mundt
215f857bceSPaul Mundt static DEFINE_SPINLOCK(die_lock);
225f857bceSPaul Mundt
die(const char * str,struct pt_regs * regs,long err)239fd5a04dSEric W. Biederman void __noreturn die(const char *str, struct pt_regs *regs, long err)
245f857bceSPaul Mundt {
255f857bceSPaul Mundt static int die_counter;
265f857bceSPaul Mundt
275f857bceSPaul Mundt oops_enter();
285f857bceSPaul Mundt
295f857bceSPaul Mundt spin_lock_irq(&die_lock);
305f857bceSPaul Mundt console_verbose();
315f857bceSPaul Mundt bust_spinlocks(1);
325f857bceSPaul Mundt
335f857bceSPaul Mundt printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
345f857bceSPaul Mundt print_modules();
355f857bceSPaul Mundt show_regs(regs);
365f857bceSPaul Mundt
375f857bceSPaul Mundt printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
385f857bceSPaul Mundt task_pid_nr(current), task_stack_page(current) + 1);
395f857bceSPaul Mundt
405f857bceSPaul Mundt if (!user_mode(regs) || in_interrupt())
41ebf0a36aSDmitry Safonov dump_mem("Stack: ", KERN_DEFAULT, regs->regs[15],
42ebf0a36aSDmitry Safonov THREAD_SIZE + (unsigned long)task_stack_page(current));
435f857bceSPaul Mundt
445f857bceSPaul Mundt notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV);
455f857bceSPaul Mundt
465f857bceSPaul Mundt bust_spinlocks(0);
47373d4d09SRusty Russell add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
485f857bceSPaul Mundt spin_unlock_irq(&die_lock);
495f857bceSPaul Mundt oops_exit();
505f857bceSPaul Mundt
515f857bceSPaul Mundt if (kexec_should_crash(current))
525f857bceSPaul Mundt crash_kexec(regs);
535f857bceSPaul Mundt
545f857bceSPaul Mundt if (in_interrupt())
555f857bceSPaul Mundt panic("Fatal exception in interrupt");
565f857bceSPaul Mundt
575f857bceSPaul Mundt if (panic_on_oops)
585f857bceSPaul Mundt panic("Fatal exception");
595f857bceSPaul Mundt
60*0e25498fSEric W. Biederman make_task_dead(SIGSEGV);
615f857bceSPaul Mundt }
625f857bceSPaul Mundt
die_if_kernel(const char * str,struct pt_regs * regs,long err)635f857bceSPaul Mundt void die_if_kernel(const char *str, struct pt_regs *regs, long err)
645f857bceSPaul Mundt {
655f857bceSPaul Mundt if (!user_mode(regs))
665f857bceSPaul Mundt die(str, regs, err);
675f857bceSPaul Mundt }
685f857bceSPaul Mundt
695f857bceSPaul Mundt /*
705f857bceSPaul Mundt * try and fix up kernelspace address errors
715f857bceSPaul Mundt * - userspace errors just cause EFAULT to be returned, resulting in SEGV
725f857bceSPaul Mundt * - kernel/userspace interfaces cause a jump to an appropriate handler
735f857bceSPaul Mundt * - other kernel errors are bad
745f857bceSPaul Mundt */
die_if_no_fixup(const char * str,struct pt_regs * regs,long err)755f857bceSPaul Mundt void die_if_no_fixup(const char *str, struct pt_regs *regs, long err)
765f857bceSPaul Mundt {
775f857bceSPaul Mundt if (!user_mode(regs)) {
785f857bceSPaul Mundt const struct exception_table_entry *fixup;
795f857bceSPaul Mundt fixup = search_exception_tables(regs->pc);
805f857bceSPaul Mundt if (fixup) {
815f857bceSPaul Mundt regs->pc = fixup->fixup;
825f857bceSPaul Mundt return;
835f857bceSPaul Mundt }
845f857bceSPaul Mundt
855f857bceSPaul Mundt die(str, regs, err);
865f857bceSPaul Mundt }
875f857bceSPaul Mundt }
885f857bceSPaul Mundt
89626ac8e1SPaul Mundt #ifdef CONFIG_GENERIC_BUG
handle_BUG(struct pt_regs * regs)90626ac8e1SPaul Mundt static void handle_BUG(struct pt_regs *regs)
915a4f7c66SPaul Mundt {
92e115f2c1SPaul Mundt const struct bug_entry *bug;
93e115f2c1SPaul Mundt unsigned long bugaddr = regs->pc;
945a4f7c66SPaul Mundt enum bug_trap_type tt;
95e115f2c1SPaul Mundt
96e115f2c1SPaul Mundt if (!is_valid_bugaddr(bugaddr))
97e115f2c1SPaul Mundt goto invalid;
98e115f2c1SPaul Mundt
99e115f2c1SPaul Mundt bug = find_bug(bugaddr);
100e115f2c1SPaul Mundt
101e115f2c1SPaul Mundt /* Switch unwinders when unwind_stack() is called */
102e115f2c1SPaul Mundt if (bug->flags & BUGFLAG_UNWINDER)
103e115f2c1SPaul Mundt unwinder_faulted = 1;
104e115f2c1SPaul Mundt
105e115f2c1SPaul Mundt tt = report_bug(bugaddr, regs);
1065a4f7c66SPaul Mundt if (tt == BUG_TRAP_TYPE_WARN) {
107e115f2c1SPaul Mundt regs->pc += instruction_size(bugaddr);
1085a4f7c66SPaul Mundt return;
1095a4f7c66SPaul Mundt }
1105a4f7c66SPaul Mundt
111e115f2c1SPaul Mundt invalid:
1125a4f7c66SPaul Mundt die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
1135a4f7c66SPaul Mundt }
1145a4f7c66SPaul Mundt
is_valid_bugaddr(unsigned long addr)1155a4f7c66SPaul Mundt int is_valid_bugaddr(unsigned long addr)
1165a4f7c66SPaul Mundt {
1172bcfffa4SPaul Mundt insn_size_t opcode;
1189a33fc21SPaul Mundt
1199a33fc21SPaul Mundt if (addr < PAGE_OFFSET)
1209a33fc21SPaul Mundt return 0;
12125f12ae4SChristoph Hellwig if (get_kernel_nofault(opcode, (insn_size_t *)addr))
1229a33fc21SPaul Mundt return 0;
123e115f2c1SPaul Mundt if (opcode == TRAPA_BUG_OPCODE)
124b344e24aSMatt Fleming return 1;
125b344e24aSMatt Fleming
126b344e24aSMatt Fleming return 0;
1275a4f7c66SPaul Mundt }
1285a4f7c66SPaul Mundt #endif
1295a4f7c66SPaul Mundt
1305a4f7c66SPaul Mundt /*
1315a4f7c66SPaul Mundt * Generic trap handler.
1325a4f7c66SPaul Mundt */
BUILD_TRAP_HANDLER(debug)1335a4f7c66SPaul Mundt BUILD_TRAP_HANDLER(debug)
1345a4f7c66SPaul Mundt {
1355a4f7c66SPaul Mundt TRAP_HANDLER_DECL;
1365a4f7c66SPaul Mundt
1375a4f7c66SPaul Mundt /* Rewind */
1389d56dd3bSPaul Mundt regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
1395a4f7c66SPaul Mundt
1405a4f7c66SPaul Mundt if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff,
1415a4f7c66SPaul Mundt SIGTRAP) == NOTIFY_STOP)
1425a4f7c66SPaul Mundt return;
1435a4f7c66SPaul Mundt
1443cf5d076SEric W. Biederman force_sig(SIGTRAP);
1455a4f7c66SPaul Mundt }
1465a4f7c66SPaul Mundt
1475a4f7c66SPaul Mundt /*
1485a4f7c66SPaul Mundt * Special handler for BUG() traps.
1495a4f7c66SPaul Mundt */
BUILD_TRAP_HANDLER(bug)1505a4f7c66SPaul Mundt BUILD_TRAP_HANDLER(bug)
1515a4f7c66SPaul Mundt {
1525a4f7c66SPaul Mundt TRAP_HANDLER_DECL;
1535a4f7c66SPaul Mundt
1545a4f7c66SPaul Mundt /* Rewind */
1559d56dd3bSPaul Mundt regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
1565a4f7c66SPaul Mundt
1575a4f7c66SPaul Mundt if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
1585a4f7c66SPaul Mundt SIGTRAP) == NOTIFY_STOP)
1595a4f7c66SPaul Mundt return;
1605a4f7c66SPaul Mundt
161626ac8e1SPaul Mundt #ifdef CONFIG_GENERIC_BUG
1625a4f7c66SPaul Mundt if (__kernel_text_address(instruction_pointer(regs))) {
1632bcfffa4SPaul Mundt insn_size_t insn = *(insn_size_t *)instruction_pointer(regs);
1645a4f7c66SPaul Mundt if (insn == TRAPA_BUG_OPCODE)
1655a4f7c66SPaul Mundt handle_BUG(regs);
1660ec39885SMagnus Damm return;
1675a4f7c66SPaul Mundt }
1685a4f7c66SPaul Mundt #endif
1695a4f7c66SPaul Mundt
1703cf5d076SEric W. Biederman force_sig(SIGTRAP);
1715a4f7c66SPaul Mundt }
1721e1030dcSPaul Mundt
173178ba00cSPeter Zijlstra #ifdef CONFIG_DYNAMIC_FTRACE
174178ba00cSPeter Zijlstra extern void arch_ftrace_nmi_enter(void);
175178ba00cSPeter Zijlstra extern void arch_ftrace_nmi_exit(void);
176178ba00cSPeter Zijlstra #else
arch_ftrace_nmi_enter(void)177178ba00cSPeter Zijlstra static inline void arch_ftrace_nmi_enter(void) { }
arch_ftrace_nmi_exit(void)178178ba00cSPeter Zijlstra static inline void arch_ftrace_nmi_exit(void) { }
179178ba00cSPeter Zijlstra #endif
180178ba00cSPeter Zijlstra
BUILD_TRAP_HANDLER(nmi)1811e1030dcSPaul Mundt BUILD_TRAP_HANDLER(nmi)
1821e1030dcSPaul Mundt {
1831e1030dcSPaul Mundt TRAP_HANDLER_DECL;
1841e1030dcSPaul Mundt
185178ba00cSPeter Zijlstra arch_ftrace_nmi_enter();
186178ba00cSPeter Zijlstra
1871e1030dcSPaul Mundt nmi_enter();
188fe3f1d5dSThomas Gleixner this_cpu_inc(irq_stat.__nmi_count);
1891e1030dcSPaul Mundt
1901e1030dcSPaul Mundt switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
1911e1030dcSPaul Mundt case NOTIFY_OK:
1921e1030dcSPaul Mundt case NOTIFY_STOP:
1931e1030dcSPaul Mundt break;
1941e1030dcSPaul Mundt case NOTIFY_BAD:
1951e1030dcSPaul Mundt die("Fatal Non-Maskable Interrupt", regs, SIGINT);
1961e1030dcSPaul Mundt default:
1971e1030dcSPaul Mundt printk(KERN_ALERT "Got NMI, but nobody cared. Ignoring...\n");
1981e1030dcSPaul Mundt break;
1991e1030dcSPaul Mundt }
2001e1030dcSPaul Mundt
2011e1030dcSPaul Mundt nmi_exit();
202178ba00cSPeter Zijlstra
203178ba00cSPeter Zijlstra arch_ftrace_nmi_exit();
2041e1030dcSPaul Mundt }
205