--- zzzz-none-000/linux-5.4.213/arch/arm/kernel/traps.c 2022-09-15 10:04:56.000000000 +0000 +++ miami-7690-761/linux-5.4.213/arch/arm/kernel/traps.c 2024-05-29 11:19:50.000000000 +0000 @@ -38,6 +38,23 @@ #include #include #include +#if defined(CONFIG_AVM_ENHANCED) +#include +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + +#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[]= { @@ -68,7 +85,12 @@ unsigned long end = frame + 4 + sizeof(struct pt_regs); #ifdef CONFIG_KALLSYMS - printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); +#if defined(CONFIG_AVM_ENHANCED) + pr_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 @@ -142,14 +164,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); @@ -187,7 +209,7 @@ printk("%sCode: %s\n", lvl, str); } -static void dump_instr(const char *lvl, struct pt_regs *regs) +static void __maybe_unused dump_instr(const char *lvl, struct pt_regs *regs) { mm_segment_t fs; @@ -204,6 +226,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 @@ -267,19 +292,47 @@ 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; + struct cpumask cpu_mask __maybe_unused; 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 /* 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(); +#if defined(CONFIG_AVM_FASTIRQ) + cpumask_clear(&cpu_mask); + cpumask_set_cpu(avm_get_crashed_cpu(), &cpu_mask); + avm_trigger_all_cpu_backtrace(regs, &cpu_mask); +#else __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)); @@ -289,8 +342,11 @@ THREAD_SIZE + (unsigned long)task_stack_page(tsk)); dump_backtrace(regs, tsk); dump_instr(KERN_EMERG, regs); +#if defined(CONFIG_AVM_ENHANCED) + show_stacktrace_memoryclassifier(regs); +#endif /* CONFIG_AVM_ENHANCED */ } - +#endif return 0; } @@ -323,7 +379,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 /* CONFIG_AVM_FASTIRQ */ + if (regs && kexec_should_crash(tsk)) crash_kexec(regs); bust_spinlocks(0); @@ -336,6 +396,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 /* CONFIG_AVM_FASTIRQ */ + if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) @@ -349,9 +414,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); @@ -361,7 +442,10 @@ 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, @@ -369,8 +453,12 @@ 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 /* CONFIG_AVM_FASTIRQ */ + tsk->thread.error_code = err; + tsk->thread.trap_no = trap; force_sig_fault(signo, si_code, addr); } else { @@ -441,9 +529,21 @@ unsigned int instr; 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 /* 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 /* CONFIG_AVM_FASTIRQ */ + ) { #ifdef CONFIG_THUMB2_KERNEL if (thumb_mode(regs)) { instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]); @@ -478,8 +578,12 @@ die_sig: #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 /* 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); } @@ -522,13 +626,30 @@ */ asmlinkage void bad_mode(struct pt_regs *regs, int reason) { +#ifndef CONFIG_AVM_FASTIRQ console_verbose(); +#endif /* 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 undefined instruction set pc on undefined instruction + * (so BUG_ON on fastirq possible), 4 == BAD_UNDEFINSTR + */ + if (reason == 4) + regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; + panic_oops_on_fiq = 1 + raw_smp_processor_id(); + } +#endif /* 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) @@ -723,13 +844,25 @@ { unsigned long addr = instruction_pointer(regs); + 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 /* CONFIG_AVM_FASTIRQ */ + #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_BADABORT) { pr_err("8<--- cut here ---\n"); + struct task_struct *tsk = current; +#if defined(CONFIG_AVM_FASTIRQ) + tsk = current_thread_info_depend_on_context(regs)->task; +#endif /* 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(KERN_ERR, current->mm, addr); + show_pte(KERN_ERR, tsk->mm, addr); } #endif