--- zzzz-none-000/linux-4.4.271/arch/arm/kernel/traps.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/arch/arm/kernel/traps.c 2023-04-19 10:22:27.000000000 +0000 @@ -38,7 +38,25 @@ #include #include #include +#if defined(CONFIG_AVM_ENHANCED) +#include +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ +#include + +#include +#include + +#if defined(CONFIG_AVM_FASTIRQ) +#include +#include +#include + +#define _BUILD_AVM_CONTEXT_FUNC(func) firq_##func +#else +#define _BUILD_AVM_CONTEXT_FUNC(func) func +#define is_avm_rte() 0 +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ static const char *handler[]= { "prefetch abort", @@ -66,7 +84,12 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS - printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_ERR"%04lx: [<%08lx>] (%pS)\n", frame & (THREAD_SIZE - 1), where, (void *)where); +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + printk(KERN_DEFAULT "[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", + where, (void *)where, from, (void *)from); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif @@ -120,14 +143,14 @@ for (p = first, i = 0; i < 8 && p < top; i++, p += 4) { if (p >= bottom && p < top) { - unsigned long val; + unsigned long val; if (__get_user(val, (unsigned long *)p) == 0) sprintf(str + i * 9, " %08lx", val); else sprintf(str + i * 9, " ????????"); } } - printk("%s%04lx:%s\n", lvl, first & 0xffff, str); + printk("%s%04lx:%s\n", lvl, first & 0xffff, str); } set_fs(fs); @@ -182,6 +205,9 @@ #ifdef CONFIG_ARM_UNWIND static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_EMERG"Backtrace:\n"); +#endif/*--- #endif ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ unwind_backtrace(regs, tsk); } #else @@ -245,30 +271,57 @@ static int __die(const char *str, int err, struct pt_regs *regs) { + static arch_spinlock_t avm_recursive_die_lock = __ARCH_SPIN_LOCK_UNLOCKED; struct task_struct *tsk = current; static int die_counter; int ret; - pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP S_ISA "\n", - str, err, ++die_counter); + if (arch_spin_trylock(&avm_recursive_die_lock)) { + +#if defined(CONFIG_AVM_FASTIRQ) + struct thread_info *pthread = NULL; + + pthread = current_thread_info_depend_on_context(regs); + if (virt_addr_valid(pthread)) { + tsk = pthread->task; + } else { + tsk = NULL; + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + + pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP S_ISA "\n", + str, err, ++die_counter); + + if (avm_is_rte_crash_handling_enabled()) + pr_err("FIQ watchdog handling, master CPU calls die notifier ...\n"); + + /* trap and error numbers are mostly meaningless on ARM */ + ret = notify_die(DIE_OOPS, str, regs, err, (tsk ? tsk->thread.trap_no : 0), SIGSEGV); + + } else { + pr_err("FIQ watchdog handling: recursion in %s...\n", __func__); + pr_err("... skipping die-notifier, falling back to single CPU backtrace!\n"); + ret = NOTIFY_OK; + } - /* trap and error numbers are mostly meaningless on ARM */ - ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); if (ret == NOTIFY_STOP) return 1; print_modules(); __show_regs(regs); pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", - TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); + TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); if (!user_mode(regs) || in_interrupt()) { - dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, - THREAD_SIZE + (unsigned long)task_stack_page(tsk)); + dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, + min((regs->ARM_sp & (~(THREAD_SIZE - 1))) + THREAD_SIZE, + (regs->ARM_sp + (PAGE_SIZE >> 1)))); dump_backtrace(regs, tsk); dump_instr(KERN_EMERG, regs); +#if defined(CONFIG_AVM_ENHANCED) + show_stacktrace_memoryclassifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } - return 0; } @@ -301,7 +354,11 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr) { - if (regs && kexec_should_crash(current)) + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + if (regs && kexec_should_crash(tsk)) crash_kexec(regs); bust_spinlocks(0); @@ -314,6 +371,11 @@ raw_local_irq_restore(flags); oops_exit(); +#if defined(CONFIG_AVM_FASTIRQ) + if (avm_is_rte_crash_handling_enabled() && panic_oops_on_fiq) + panic("Fatal exception in fastirq"); +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) @@ -327,9 +389,25 @@ */ void die(const char *str, struct pt_regs *regs, int err) { - enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; - unsigned long flags = oops_begin(); int sig = SIGSEGV; + unsigned long flags; + enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; + + if (avm_is_rte_crash_handling_enabled()) { + switch (avm_rte_die(str, regs)) { + case AVM_RTE_DIE_CALL_DIE: + die(str, regs, err); + break; + case AVM_RTE_DIE_TRIGGER_WD: + __set_ICDISPR(get_wdt_int(), 1, 0); + while (1) + ; + break; + case AVM_RTE_DIE_CONTINUE: + break; + } + } else + flags = oops_begin(); if (!user_mode(regs)) bug_type = report_bug(regs->ARM_pc, regs); @@ -339,17 +417,24 @@ if (__die(str, err, regs)) sig = 0; - oops_end(flags, regs, sig); + if (avm_is_rte_crash_handling_enabled()) + avm_die(); + else + oops_end(flags, regs, sig); } void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, unsigned long err, unsigned long trap) { if (user_mode(regs)) { - current->thread.error_code = err; - current->thread.trap_no = trap; + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif + tsk->thread.error_code = err; + tsk->thread.trap_no = trap; - force_sig_info(info->si_signo, info, current); + force_sig_info(info->si_signo, info, tsk); } else { die(str, regs, err); } @@ -419,9 +504,21 @@ siginfo_t info; void __user *pc; + start_avm_crash_path(regs); + +#if defined(CONFIG_AVM_FASTIRQ) + if(processor_mode(regs) == FIQ_MODE) { + panic_oops_on_fiq = 1 + raw_smp_processor_id(); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + early_printk("%s\n", __func__); pc = (void __user *)instruction_pointer(regs); - if (processor_mode(regs) == SVC_MODE) { + if (processor_mode(regs) == SVC_MODE +#if defined(CONFIG_AVM_FASTIRQ) + || (processor_mode(regs) == FIQ_MODE) +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + ) { #ifdef CONFIG_THUMB2_KERNEL if (thumb_mode(regs)) { instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]); @@ -454,10 +551,16 @@ return; die_sig: + trace_undef_instr(regs, (void *)pc); + #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ pr_info("%s (%d): undefined instruction: pc=%p\n", - current->comm, task_pid_nr(current), pc); + tsk->comm, task_pid_nr(tsk), pc); __show_regs(regs); dump_instr(KERN_INFO, regs); } @@ -505,13 +608,28 @@ */ asmlinkage void bad_mode(struct pt_regs *regs, int reason) { +#if !defined(CONFIG_AVM_FASTIRQ) console_verbose(); +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ pr_crit("Bad mode in %s handler detected\n", handler[reason]); + start_avm_crash_path(regs); + +#if defined(CONFIG_AVM_FASTIRQ) + if(processor_mode(regs) == FIQ_MODE) { + if(reason == 4 /* BAD_UNDEFINSTR */) { + regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; /*--- if undefined instruction so set pc on undefined instruction (so BUG_ON on fastirq possible) ---*/ + } + panic_oops_on_fiq = 1 + raw_smp_processor_id(); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + die("Oops - bad mode", regs, 0); +#if !defined(CONFIG_AVM_FASTIRQ) local_irq_disable(); panic("bad mode"); +#endif } static int bad_syscall(int n, struct pt_regs *regs) @@ -581,6 +699,7 @@ * 0x9f0000 - 0x9fffff are some more esoteric system calls */ #define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE) + asmlinkage int arm_syscall(int no, struct pt_regs *regs) { siginfo_t info; @@ -718,12 +837,24 @@ unsigned long addr = instruction_pointer(regs); siginfo_t info; + start_avm_crash_path(regs); + +#if defined(CONFIG_AVM_FASTIRQ) + if(processor_mode(regs) == FIQ_MODE) { + panic_oops_on_fiq = 1 + raw_smp_processor_id(); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_BADABORT) { + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ pr_err("[%d] %s: bad data abort: code %d instr 0x%08lx\n", task_pid_nr(current), current->comm, code, instr); dump_instr(KERN_ERR, regs); - show_pte(current->mm, addr); + show_pte(tsk->mm, addr); } #endif