diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 314e8a5436d1..fead7137c8d2 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -394,6 +394,9 @@ END(vectors) mov x0, sp mov x1, #\reason mrs x2, esr_el1 +#ifdef CONFIG_AMLOGIC_USER_FAULT + mrs x3, far_el1 +#endif b bad_mode .endm @@ -516,6 +519,9 @@ el1_inv: mov x0, sp mov x2, x1 mov x1, #BAD_SYNC +#ifdef CONFIG_AMLOGIC_USER_FAULT + mrs x3, far_el1 +#endif b bad_mode ENDPROC(el1_sync) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 62961043cdba..b2b036beb019 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -639,7 +639,12 @@ const char *esr_get_class_string(u32 esr) * bad_mode handles the impossible case in the exception vector. This is always * fatal. */ +#ifdef CONFIG_AMLOGIC_USER_FAULT +asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr, + unsigned long far) +#else asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) +#endif { console_verbose(); @@ -647,6 +652,11 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) handler[reason], smp_processor_id(), esr, esr_get_class_string(esr)); +#ifdef CONFIG_AMLOGIC_USER_FAULT + regs->unused = far; + pr_crit("FAR:%lx\n", far); + show_all_pfn(current, regs); +#endif /* CONFIG_AMLOGIC_USER_FAULT */ die("Oops - bad mode", regs, 0); local_irq_disable(); panic("bad mode"); diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 719108eaff7b..d97e502e6d9f 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -275,6 +275,13 @@ void show_all_pfn(struct task_struct *task, struct pt_regs *regs) else sprintf(s1, "--------"); pr_info("sp : %016llx %s\n", regs->sp, s1); + + pfn1 = get_user_pfn(task->mm, regs->unused); + if (pfn1 >= 0) + sprintf(s1, "%8lx", pfn1); + else + sprintf(s1, "--------"); + pr_info("unused : %016llx %s\n", regs->unused, s1); } #endif /* CONFIG_AMLOGIC_USER_FAULT */