--- zzzz-none-000/linux-4.4.60/arch/mips/kernel/traps.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-1750e-727/linux-4.4.60/arch/mips/kernel/traps.c 2021-02-04 17:41:59.000000000 +0000 @@ -64,6 +64,15 @@ #include #include #include +#if defined(CONFIG_AVM_SIMPLE_PROFILING) +#include +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ +#if defined(CONFIG_AVM_ENHANCED) +#include +#include +#include +extern unsigned long kernelsp[NR_CPUS]; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ extern void check_wait(void); extern asmlinkage void rollback_handle_int(void); @@ -108,21 +117,23 @@ unsigned long *sp = (unsigned long *)(reg29 & ~3); unsigned long addr; - printk("Call Trace:"); -#ifdef CONFIG_KALLSYMS - printk("\n"); -#endif + printk(KERN_EMERG"Call Trace:\n"); while (!kstack_end(sp)) { unsigned long __user *p = (unsigned long __user *)(unsigned long)sp++; if (__get_user(addr, p)) { - printk(" (Bad stack address)"); + printk(KERN_EMERG" (Bad stack address)"); break; } - if (__kernel_text_address(addr)) + if (__kernel_text_address(addr)) { +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_EMERG"%04lx: [<%p>] %pS\n", (unsigned long)sp & THREAD_MASK,(void *) addr, (void *) addr); +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ print_ip_sym(addr); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + } } - printk("\n"); + printk(KERN_EMERG"\n"); } #ifdef CONFIG_KALLSYMS @@ -135,11 +146,15 @@ __setup("raw_show_trace", set_raw_show_trace); #endif -static void show_backtrace(struct task_struct *task, const struct pt_regs *regs) +void show_backtrace(struct task_struct *task, const struct pt_regs *regs) { unsigned long sp = regs->regs[29]; unsigned long ra = regs->regs[31]; unsigned long pc = regs->cp0_epc; +#if defined(CONFIG_AVM_ENHANCED) + unsigned long first_ra = ra; + unsigned long first_sp = sp; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (!task) task = current; @@ -148,12 +163,33 @@ show_raw_backtrace(sp); return; } - printk("Call Trace:\n"); + printk(KERN_EMERG"Call Trace:\n"); do { - print_ip_sym(pc); +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_EMERG"%04lx: [<%p>] %pS\n", sp & THREAD_MASK,(void *) pc, (void *) pc); +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + print_ip_sym(pc); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ pc = unwind_stack(task, &sp, pc, &ra); +#if defined(CONFIG_AVM_ENHANCED) + if(first_ra) { + if(pc == 0) { + /**--------------------------------------------------------------------------------**\ + * es gibt Funktionen (z.B. _raw_spin_lock_bh), wo direkt in eine andere Funktion + * per bxx symbol+offset(!=0) (z.b. _raw_read_unlock_bh+0xa4) gesprungen wird. In diesem Fall + * funktioniert die Ermittlung von ra ueber den Stack nicht, da der Stackoffset der + * angeprungenen Funktion mit Offset 0 ermittelt wird - passiert dies beim ersten Aufruf + * wo ja ra noch korrekt im Register koennen wir hier das ra direkt verwenden + * (siehe JZ-30655) + \**--------------------------------------------------------------------------------**/ + pc = first_ra; + sp = first_sp; + } + first_ra = 0; /*--- nur initial das Register ra verwenden ---*/ + } +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } while (pc); - printk("\n"); + printk(KERN_EMERG"\n"); } /* @@ -187,6 +223,9 @@ i++; } printk("\n"); +#if defined(CONFIG_AVM_ENHANCED) + show_stacktrace_memoryclassifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ show_backtrace(task, regs); } @@ -226,22 +265,39 @@ long i; unsigned short __user *pc16 = NULL; - printk("\nCode:"); + printk(KERN_ERR"\nCode:"); if ((unsigned long)pc & 1) pc16 = (unsigned short __user *)((unsigned long)pc & ~1); for(i = -3 ; i < 6 ; i++) { unsigned int insn; if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) { - printk(" (Bad address in epc)\n"); + printk(KERN_ERR" (Bad address in epc)\n"); break; } printk("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>')); } } +#if defined(CONFIG_AVM_ENHANCED) +char *get_kernel_or_user_symbol(char *txt, unsigned int maxttxlen, const struct pt_regs *regs, unsigned long addr){ + unsigned long gp; + txt[0] = 0; + if(!user_mode(regs)) { + snprintf(txt, maxttxlen, "%pS", (void *)addr); + return txt; + } + /*--- wir sind im USER-Mode: Spezialbehandlung fuer gp-Ermittlung (da virtuelle Adressen) ---*/ + gp = kernelsp[smp_processor_id()] & ~THREAD_MASK; /*--- kseg0-gp ermitteln ---*/ + return get_user_symbol(txt, maxttxlen, gp, addr); +} +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + static void __show_regs(const struct pt_regs *regs) { +#if defined(CONFIG_AVM_ENHANCED) + char txt[KSYM_NAME_LEN]; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ const int field = 2 * sizeof(unsigned long); unsigned int cause = regs->cp0_cause; unsigned int exccode; @@ -268,20 +324,23 @@ } #ifdef CONFIG_CPU_HAS_SMARTMIPS - printk("Acx : %0*lx\n", field, regs->acx); + printk(KERN_ERR"Acx : %0*lx\n", field, regs->acx); #endif - printk("Hi : %0*lx\n", field, regs->hi); - printk("Lo : %0*lx\n", field, regs->lo); + printk(KERN_ERR"Hi : %0*lx\n", field, regs->hi); + printk(KERN_ERR"Lo : %0*lx\n", field, regs->lo); +#if !defined(CONFIG_AVM_ENHANCED) /* * Saved cp0 registers */ printk("epc : %0*lx %pS\n", field, regs->cp0_epc, (void *) regs->cp0_epc); - printk("ra : %0*lx %pS\n", field, regs->regs[31], + printk(KERN_ERR" %s\n", print_tainted()); + printk(KERN_ERR"ra : %0*lx %pS\n", field, regs->regs[31], (void *) regs->regs[31]); +#endif/*--- #if !defined(CONFIG_AVM_ENHANCED) ---*/ - printk("Status: %08x ", (uint32_t) regs->cp0_status); + printk(KERN_ERR"Status: %08x ", (uint32_t) regs->cp0_status); if (cpu_has_3kex) { if (regs->cp0_status & ST0_KUO) @@ -323,17 +382,43 @@ printk("EXL "); if (regs->cp0_status & ST0_IE) printk("IE "); + if (regs->cp0_status & ST0_NMI) + printk("NMI"); } printk("\n"); exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE; +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_ERR"Cause : %08x exc_code:%d %s\n", cause, exccode, + exccode == 1 ? "Mod" : + exccode == 2 ? "TLBL" : + exccode == 3 ? "TLBS" : + exccode == 4 ? "AdEL" : + exccode == 5 ? "AdES" : + exccode == 6 ? "IBE" : + exccode == 7 ? "DBE" : + exccode == 25 ? "Thread" : + exccode == 23 ? "WATCH" : + exccode == 31 ? "CacheErr" : "" + ); +#else /*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ printk("Cause : %08x (ExcCode %02x)\n", cause, exccode); +#endif if (1 <= exccode && exccode <= 5) - printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr); + printk(KERN_ERR"BadVA : %0*lx\n", field, regs->cp0_badvaddr); +#if defined(CONFIG_AVM_ENHANCED) +/*--- printk(KERN_ERR"errepc: %08lx %pS\n", read_c0_errorepc(), (void *)read_c0_errorepc()); ---*/ + printk(KERN_ERR"epc : %0*lx %s\n", field, regs->cp0_epc, get_kernel_or_user_symbol(txt, sizeof(txt), regs, regs->cp0_epc)); + printk(KERN_ERR"ra : %0*lx %s\n", field, regs->regs[31], get_kernel_or_user_symbol(txt, sizeof(txt), regs, regs->regs[31])); + printk(KERN_ERR" %s\n", print_tainted()); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ printk("PrId : %08x (%s)\n", read_c0_prid(), cpu_name_string()); +#if defined(CONFIG_AVM_ENHANCED) + show_register_memoryclassifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } /* @@ -344,7 +429,7 @@ __show_regs((struct pt_regs *)regs); } -void show_registers(struct pt_regs *regs) +void show_registers(const struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); mm_segment_t old_fs = get_fs(); @@ -436,6 +521,10 @@ int action = MIPS_BE_FATAL; enum ctx_state prev_state; +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_begin, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ prev_state = exception_enter(); /* XXX For now. Fixme, this searches the wrong table ... */ if (data && !user_mode(regs)) @@ -447,6 +536,10 @@ if (board_be_handler) action = board_be_handler(regs, fixup != NULL); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_end, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ switch (action) { case MIPS_BE_DISCARD: goto out; @@ -697,6 +790,9 @@ }; prev_state = exception_enter(); +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel integer overflow", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ die_if_kernel("Integer overflow", regs); force_sig_info(SIGFPE, &info, current); @@ -822,6 +918,9 @@ int sig; prev_state = exception_enter(); +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel-floatingpoint-exception", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (notify_die(DIE_FP, "FP exception", regs, 0, current->thread.trap_nr, SIGFPE) == NOTIFY_STOP) goto out; @@ -907,6 +1006,9 @@ force_sig_info(SIGFPE, &info, current); break; case BRK_BUG: +#if defined(CONFIG_AVM_ENHANCED) + show_bug_by_bugtable(regs); +#endif /*--- #ifdef CONFIG_BUG_EXTRA_INFO ---*/ die_if_kernel("Kernel bug detected", regs); force_sig(SIGTRAP, current); break; @@ -943,6 +1045,9 @@ if (!user_mode(regs)) set_fs(KERNEL_DS); +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel-breakpoint", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ prev_state = exception_enter(); current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f; if (get_isa16_mode(regs->cp0_epc)) { @@ -1031,6 +1136,9 @@ u16 instr[2]; mm_segment_t seg; unsigned long epc = msk_isa16_mode(exception_epc(regs)); +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel-trap", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ seg = get_fs(); if (!user_mode(regs)) @@ -1507,7 +1615,21 @@ { enum ctx_state prev_state; u32 cause; - +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_begin, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + +#if defined(CONFIG_AVM_WP) + if (avm_wp_dispatcher(regs)) { +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_end, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + local_irq_enable(); + return; + } +#endif prev_state = exception_enter(); /* * Clear WP (bit 22) bit of cause register so we don't loop @@ -1530,6 +1652,10 @@ mips_clear_watch_registers(); local_irq_enable(); } +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_end, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ exception_exit(prev_state); } @@ -1855,13 +1981,15 @@ void __noreturn nmi_exception_handler(struct pt_regs *regs) { char str[100]; - +#if defined(CONFIG_AVM_ENHANCED) + avm_tick_jiffies_update(); /*--- auch im NMI-Fall jiffies korrigieren ---*/ +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ nmi_enter(); raw_notifier_call_chain(&nmi_chain, 0, regs); bust_spinlocks(1); + regs->cp0_epc = read_c0_errorepc(); snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n", smp_processor_id(), regs->cp0_epc); - regs->cp0_epc = read_c0_errorepc(); die(str, regs); nmi_exit(); }