/* * bad_mode handles the impossible case in the exception vector. */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); console_verbose(); #ifdef CONFIG_MEDIATEK_SOLUTION /* * * reason is defined in entry.S, 3 means BAD_ERROR, * * which would be triggered by async abort */ if ((reason == 3) && async_abort_handler) async_abort_handler(regs, async_abort_priv); #endif pr_crit("Bad mode in %s handler detected, code 0x%08x\n", handler[reason], esr); __show_regs(regs); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - bad mode", regs, &info, 0); }
void force_signal_inject(int signal, int code, unsigned long address) { const char *desc; struct pt_regs *regs = current_pt_regs(); if (WARN_ON(!user_mode(regs))) return; switch (signal) { case SIGILL: desc = "undefined instruction"; break; case SIGSEGV: desc = "illegal memory access"; break; default: desc = "unknown or unrecoverable error"; break; } /* Force signals we don't understand to SIGKILL */ if (WARN_ON(signal != SIGKILL && siginfo_layout(signal, code) != SIL_FAULT)) { signal = SIGKILL; } arm64_notify_die(desc, regs, signal, code, (void __user *)address, 0); }
static void force_signal_inject(int signal, int code, struct pt_regs *regs, unsigned long address) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); const char *desc; switch (signal) { case SIGILL: desc = "undefined instruction"; break; case SIGSEGV: desc = "illegal memory access"; break; default: desc = "bad mode"; break; } if (unhandled_signal(current, signal) && show_unhandled_signals_ratelimited()) { pr_info("%s[%d]: %s: pc=%p\n", current->comm, task_pid_nr(current), desc, pc); dump_instr(KERN_INFO, regs); } info.si_signo = signal; info.si_errno = 0; info.si_code = code; info.si_addr = pc; arm64_notify_die(desc, regs, &info, 0); }
asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); /* check for AArch32 breakpoint instructions */ if (!aarch32_break_handler(regs)) return; if (call_undef_hook(regs) == 0) return; if (show_unhandled_signals && unhandled_signal(current, SIGILL) && printk_ratelimit()) { pr_info("%s[%d]: undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); dump_instr(KERN_INFO, regs); } info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - undefined instruction", regs, &info, 0); }
asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); /* check for AArch32 breakpoint instructions */ if (!aarch32_break_handler(regs)) return; if (call_undef_hook(regs) == 0) return; if (unhandled_signal(current, SIGILL) && show_unhandled_signals_ratelimited()) { #ifdef CONFIG_HUAWEI_PRINTK_CTRL printk_level_setup(LOGLEVEL_DEBUG); #endif pr_info("%s[%d]: undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); dump_instr(KERN_INFO, regs); #ifdef CONFIG_HUAWEI_PRINTK_CTRL printk_level_setup(sysctl_printk_level); #endif } info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - undefined instruction", regs, &info, 0); }
/* * Handle stack alignment exceptions. */ asmlinkage void __exception do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { struct siginfo info; info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; info.si_addr = (void __user *)addr; arm64_notify_die("", regs, &info, esr); }
asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { u32 instr; siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); struct thread_info *thread = current_thread_info(); /* check for AArch32 breakpoint instructions */ if (!aarch32_break_handler(regs)) return; if (user_mode(regs)) { if (compat_thumb_mode(regs)) { if (get_user(instr, (u16 __user *)pc)) goto die_sig; if (is_wide_instruction(instr)) { u32 instr2; if (get_user(instr2, (u16 __user *)pc+1)) goto die_sig; instr <<= 16; instr |= instr2; } } else if (get_user(instr, (u32 __user *)pc)) { goto die_sig; } } else { /* kernel mode */ instr = *((u32 *)pc); } if (call_undef_hook(regs, instr) == 0) return; die_sig: if (show_unhandled_signals && unhandled_signal(current, SIGILL) && printk_ratelimit()) { pr_info("%s[%d]: undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); dump_instr(KERN_INFO, regs); } info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - undefined instruction", regs, &info, 0); }
/* * bad_mode handles the impossible case in the exception vector. */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); console_verbose(); pr_crit("Bad mode in %s handler detected, code 0x%08x\n", handler[reason], esr); __show_regs(regs); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - bad mode", regs, &info, 0); }
/* * Dispatch a data abort to the relevant handler. */ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { const struct fault_info *inf = fault_info + (esr & 63); struct siginfo info; if (!inf->fn(addr, esr, regs)) return; pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n", inf->name, esr, addr); info.si_signo = inf->sig; info.si_errno = 0; info.si_code = inf->code; info.si_addr = (void __user *)addr; arm64_notify_die("", regs, &info, esr); }
/* * Handle stack alignment exceptions. */ asmlinkage void __exception do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { struct siginfo info; struct task_struct *tsk = current; if (show_unhandled_signals && unhandled_signal(tsk, SIGBUS)) pr_info_ratelimited("%s[%d]: %s exception: pc=%p sp=%p\n", tsk->comm, task_pid_nr(tsk), esr_get_class_string(esr), (void *)regs->pc, (void *)regs->sp); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; info.si_addr = (void __user *)addr; arm64_notify_die("Oops - SP/PC alignment exception", regs, &info, esr); }
asmlinkage int __exception do_debug_exception(unsigned long addr, unsigned int esr, struct pt_regs *regs) { const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr); struct siginfo info; if (!inf->fn(addr, esr, regs)) return 1; pr_alert("Unhandled debug exception: %s (0x%08x) at 0x%016lx\n", inf->name, esr, addr); info.si_signo = inf->sig; info.si_errno = 0; info.si_code = inf->code; info.si_addr = (void __user *)addr; arm64_notify_die("", regs, &info, 0); return 0; }
asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); #ifdef CONFIG_COMPAT /* check for AArch32 breakpoint instructions */ if (compat_user_mode(regs) && aarch32_break_trap(regs) == 0) return; #endif if (show_unhandled_signals) { pr_info("%s[%d]: undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); dump_instr(KERN_INFO, regs); } info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - undefined instruction", regs, &info, 0); }