--- zzzz-none-000/linux-4.4.60/arch/mips/kernel/traps.c 2017-04-08 07:53:53.000000000 +0000 +++ dragonfly-4020-701/linux-4.4.60/arch/mips/kernel/traps.c 2018-11-08 13:36:17.000000000 +0000 @@ -64,6 +64,12 @@ #include #include #include +#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 +114,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 +143,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 +160,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 +220,9 @@ i++; } printk("\n"); +#if defined(CONFIG_AVM_ENHANCED) + show_stacktrace_memoryclassifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ show_backtrace(task, regs); } @@ -240,8 +276,25 @@ } } +#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[64]; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ const int field = 2 * sizeof(unsigned long); unsigned int cause = regs->cp0_cause; unsigned int exccode; @@ -273,6 +326,7 @@ printk("Hi : %0*lx\n", field, regs->hi); printk("Lo : %0*lx\n", field, regs->lo); +#if !defined(CONFIG_AVM_ENHANCED) /* * Saved cp0 registers */ @@ -280,6 +334,7 @@ (void *) regs->cp0_epc); printk("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); @@ -323,17 +378,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); +#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_memory_classifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } /* @@ -697,6 +778,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 +906,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 +994,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 +1033,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 +1124,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)) @@ -1508,6 +1604,12 @@ enum ctx_state prev_state; u32 cause; +#if defined(CONFIG_AVM_WP) + if (avm_wp_dispatcher(regs)) { + local_irq_enable(); + return; + } +#endif prev_state = exception_enter(); /* * Clear WP (bit 22) bit of cause register so we don't loop @@ -1855,13 +1957,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(); }