--- zzzz-none-000/linux-4.4.271/arch/arm/mm/fault.c 2021-06-03 06:22:09.000000000 +0000 +++ dakota-7530ac-750/linux-4.4.271/arch/arm/mm/fault.c 2023-01-11 09:25:41.000000000 +0000 @@ -25,9 +25,21 @@ #include #include #include +#if defined(CONFIG_AVM_SIMPLE_PROFILING) +#include +#endif/*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ +#if defined(CONFIG_AVM_POWER) +#include +#endif /*--- #if defined(CONFIG_AVM_POWER) ---*/ + +#if defined(CONFIG_AVM_FASTIRQ) +#include +#endif/*--- #if defined(CONFIG_AVM_FASTIRQ) ---*/ #include "fault.h" +#include + #ifdef CONFIG_MMU #ifdef CONFIG_KPROBES @@ -132,6 +144,9 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, struct pt_regs *regs) { +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; +#endif /* * Are we prepared to handle this kernel fault? */ @@ -141,6 +156,10 @@ /* * No handler, we'll have to terminate things with extreme prejudice. */ +#if defined(CONFIG_AVM_FASTIRQ) + prepare_register_for_trap(&fregs, ®s); + set_exc_regs(regs); +#endif bust_spinlocks(1); pr_alert("Unable to handle kernel %s at virtual address %08lx\n", (addr < PAGE_SIZE) ? "NULL pointer dereference" : @@ -163,6 +182,7 @@ { struct siginfo si; + trace_user_fault(tsk, addr, fsr); if (addr > TASK_SIZE) harden_branch_predictor(); @@ -246,7 +266,18 @@ goto out; } - return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); + /* + * If for any reason at all we couldn't handle the fault, make + * sure we exit gracefully rather than endlessly redo the fault. + */ +#if defined(CONFIG_AVM_POWER) + avm_page_statistic_fault_get(); +#endif/*--- #if defined(CONFIG_AVM_POWER) ---*/ + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); +#if defined(CONFIG_AVM_POWER) + avm_page_statistic_fault_put(); +#endif/*--- #if defined(CONFIG_AVM_POWER) ---*/ + return fault; check_stack: /* Don't allow expansion below FIRST_USER_ADDRESS */ @@ -265,6 +296,10 @@ int fault, sig, code; unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_enter_irq_context(regs->ARM_pc, regs->ARM_lr); +#endif/*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + if (notify_page_fault(regs, fsr)) return 0; @@ -311,7 +346,13 @@ #endif } +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_hw_irq_begin, (unsigned int)regs->ARM_pc, AVM_PROFILE_PAGE_FAULT_ID); +#endif/*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ fault = __do_page_fault(mm, addr, fsr, flags, tsk); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_hw_irq_end, (unsigned int)regs->ARM_pc, AVM_PROFILE_PAGE_FAULT_ID); +#endif/*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ /* If we need to retry but a fatal signal is pending, handle the * signal first. We do not need to release the mmap_sem because @@ -436,6 +477,10 @@ if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_enter_irq_context(regs->ARM_pc, regs->ARM_lr); +#endif/*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + if (user_mode(regs)) goto bad_area; @@ -553,11 +598,22 @@ const struct fsr_info *inf = fsr_info + fsr_fs(fsr); struct siginfo info; +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; +#endif if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) return; pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); + +#if defined(CONFIG_AVM_FASTIRQ) + if (!user_mode(regs)) { + prepare_register_for_trap(&fregs, ®s); + set_exc_regs(regs); + } +#endif + show_pte(current->mm, addr); info.si_signo = inf->sig; @@ -586,12 +642,22 @@ const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr); struct siginfo info; +#if defined(CONFIG_AVM_FASTIRQ) + struct pt_regs fregs; +#endif if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) return; pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", inf->name, ifsr, addr); +#if defined(CONFIG_AVM_FASTIRQ) + if (!user_mode(regs)) { + prepare_register_for_trap(&fregs, ®s); + set_exc_regs(regs); + } +#endif + info.si_signo = inf->sig; info.si_errno = 0; info.si_code = inf->code;