--- zzzz-none-000/linux-4.4.60/arch/mips/kernel/unaligned.c 2017-04-08 07:53:53.000000000 +0000 +++ dragonfly-4020-701/linux-4.4.60/arch/mips/kernel/unaligned.c 2018-11-08 13:36:17.000000000 +0000 @@ -90,6 +90,9 @@ #include #include #include +#if defined(CONFIG_AVM_ENHANCED) +#include +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ #define STR(x) __STR(x) #define __STR(x) #x @@ -892,6 +895,9 @@ #ifdef CONFIG_EVA mm_segment_t seg; #endif +#if defined(CONFIG_AVM_ENHANCED) + siginfo_t info; +#endif union fpureg *fpr; enum msa_2b_fmt df; unsigned int wd; @@ -1331,20 +1337,42 @@ return; die_if_kernel("Unhandled kernel unaligned access", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = SEGV_ACCERR; + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGSEGV, &info, current); +#else force_sig(SIGSEGV, current); - +#endif return; sigbus: die_if_kernel("Unhandled kernel unaligned access", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = BUS_ADRERR; + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGBUS, &info, current); +#else force_sig(SIGBUS, current); - +#endif return; sigill: die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = ILL_ILLOPC; + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGILL, &info, current); +#else force_sig(SIGILL, current); +#endif } /* Recode table from 16-bit register notation to 32-bit GPR. */ @@ -1368,6 +1396,9 @@ union mips_instruction insn; struct mm_decoded_insn mminsn; void __user *fault_addr = NULL; +#if defined(CONFIG_AVM_ENHANCED) + siginfo_t info; +#endif origpc = regs->cp0_epc; orig31 = regs->regs[31]; @@ -1958,20 +1989,42 @@ return; die_if_kernel("Unhandled kernel unaligned access", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = SEGV_ACCERR; + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGSEGV, &info, current); +#else force_sig(SIGSEGV, current); - +#endif return; sigbus: die_if_kernel("Unhandled kernel unaligned access", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = BUS_ADRERR; + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGBUS, &info, current); +#else force_sig(SIGBUS, current); - +#endif return; sigill: die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = ILL_ILLOPC; + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGILL, &info, current); +#else force_sig(SIGILL, current); +#endif } static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr) @@ -1983,6 +2036,9 @@ u16 __user *pc16; unsigned long origpc; union mips16e_instruction mips16inst, oldinst; +#if defined(CONFIG_AVM_ENHANCED) + siginfo_t info; +#endif origpc = regs->cp0_epc; orig31 = regs->regs[31]; @@ -2203,20 +2259,42 @@ return; die_if_kernel("Unhandled kernel unaligned access", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = SEGV_ACCERR; + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGSEGV, &info, current); +#else force_sig(SIGSEGV, current); - +#endif return; sigbus: die_if_kernel("Unhandled kernel unaligned access", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = BUS_ADRERR; + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGBUS, &info, current); +#else force_sig(SIGBUS, current); - +#endif return; sigill: die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = ILL_ILLOPC; + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGILL, &info, current); +#else force_sig(SIGILL, current); +#endif } asmlinkage void do_ade(struct pt_regs *regs) @@ -2224,6 +2302,9 @@ enum ctx_state prev_state; unsigned int __user *pc; mm_segment_t seg; +#if defined(CONFIG_AVM_ENHANCED) + siginfo_t info; +#endif prev_state = exception_enter(); perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, @@ -2233,7 +2314,11 @@ */ if (regs->cp0_badvaddr == regs->cp0_epc) goto sigbus; - +#if defined(CONFIG_AVM_ENHANCED) + if(show_unaligned_position(regs)) { + goto sigbus; + } +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (user_mode(regs) && !test_thread_flag(TIF_FIXADE)) goto sigbus; if (unaligned_action == UNALIGNED_ACTION_SIGNAL) @@ -2296,8 +2381,15 @@ sigbus: die_if_kernel("Kernel unaligned instruction access", regs); +#if defined(CONFIG_AVM_ENHANCED) + info.si_code = BUS_ADRERR; + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_addr = (void __user *) regs->cp0_badvaddr; + force_sig_info(SIGBUS, &info, current); +#else force_sig(SIGBUS, current); - +#endif /* * XXX On return from the signal handler we should advance the epc */