--- zzzz-none-000/linux-4.4.60/arch/arm/kernel/traps.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-7490-727/linux-4.4.60/arch/arm/kernel/traps.c 2021-02-04 17:41:59.000000000 +0000 @@ -37,7 +37,27 @@ #include #include #include +#if defined(CONFIG_AVM_ENHANCED) +#include +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ +#include + +#if defined(CONFIG_AVM_FASTIRQ) +int in_avm_wdt_handling(void); +void avm_die_panic_handling(const char *str, struct pt_regs *regs); + +void avm_die(void); + +#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", @@ -65,7 +85,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 @@ -119,14 +144,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); @@ -173,6 +198,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 @@ -240,29 +268,57 @@ static int die_counter; int ret; - pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP S_ISA "\n", - str, err, ++die_counter); + static DEFINE_SPINLOCK(avm_recursive_die_lock); + + if (_BUILD_AVM_CONTEXT_FUNC(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 defined(CONFIG_AVM_FASTIRQ) + printk( KERN_ERR "FIQ watchdog handling, master CPU calls die notifier ...\n" ); +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + /* trap and error numbers are mostly meaningless on ARM */ + ret = notify_die(DIE_OOPS, str, regs, err, (tsk ? tsk->thread.trap_no : 0), SIGSEGV); + + _BUILD_AVM_CONTEXT_FUNC(spin_unlock(&avm_recursive_die_lock)); + } else { + printk( KERN_ERR "FIQ watchdog handling: recursion in __die ...\n" ); + ret = NOTIFY_STOP; + } - /* 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, + 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/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } - return 0; } +#if !defined(CONFIG_AVM_FASTIRQ) static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; static int die_owner = -1; static unsigned int die_nest_count; @@ -292,7 +348,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); @@ -305,6 +365,11 @@ raw_local_irq_restore(flags); oops_exit(); +#if defined(CONFIG_AVM_FASTIRQ) + if(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) @@ -312,36 +377,68 @@ if (signr) do_exit(signr); } +#endif /* * This function is protected against re-entrancy. */ 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; - - if (!user_mode(regs)) - bug_type = report_bug(regs->ARM_pc, regs); - if (bug_type != BUG_TRAP_TYPE_NONE) - str = "Oops - BUG"; - if (__die(str, err, regs)) - sig = 0; +#if defined(CONFIG_AVM_FASTIRQ) + if( !in_avm_wdt_handling() ) { +#ifdef CONFIG_AVM_DEBUG + printk_avm_console_bend(0); +#endif + printk( KERN_INFO "Generic die() handling triggers AVM WD ...\n" ); + avm_die_panic_handling(str, regs); + } +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + { + enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; +#if !defined(CONFIG_AVM_FASTIRQ) + unsigned long flags = oops_begin(); + int sig = SIGSEGV; +#else + int sig = SIGSEGV; - oops_end(flags, regs, sig); + tracing_off(); + /* Kernel Integritaet nicht mehr vertrauenswürdig */ + debug_locks_off(); + + bust_spinlocks(1); +#endif + if (!user_mode(regs)) + bug_type = report_bug(regs->ARM_pc, regs); + if (bug_type != BUG_TRAP_TYPE_NONE) + str = "Oops - BUG"; + + if (__die(str, err, regs)) + sig = 0; +#if !defined(CONFIG_AVM_FASTIRQ) + oops_end(flags, regs, sig); +#else + if( in_avm_wdt_handling() ) { + avm_die(); + return; + } +#endif + } } 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/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ + tsk->thread.error_code = err; + tsk->thread.trap_no = trap; - force_sig_info(info->si_signo, info, current); - } else { + force_sig_info(info->si_signo, info, tsk); + } else { die(str, regs, err); } } @@ -409,9 +506,26 @@ siginfo_t info; void __user *pc; +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; + + prepare_register_for_trap(&fregs, ®s); + if (!user_mode(regs)) { + set_exc_regs(regs); + } + + 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]); @@ -444,10 +558,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); } @@ -494,13 +614,33 @@ */ asmlinkage void bad_mode(struct pt_regs *regs, int reason) { +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; +#else console_verbose(); +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ pr_crit("Bad mode in %s handler detected\n", handler[reason]); +#if defined(CONFIG_AVM_FASTIRQ) + prepare_register_for_trap(&fregs, ®s); + if (!user_mode(regs)) { + set_exc_regs(regs); + } + + 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) @@ -570,6 +710,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; @@ -707,12 +848,29 @@ unsigned long addr = instruction_pointer(regs); siginfo_t info; +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; + + prepare_register_for_trap(&fregs, ®s); + if (!user_mode(regs)) { + set_exc_regs(regs); + } + + 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