mm: show more information when in bad mode [1/1]
authortao zeng <tao.zeng@amlogic.com>
Wed, 17 Oct 2018 09:55:46 +0000 (17:55 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 19 Oct 2018 01:23:37 +0000 (18:23 -0700)
PD#154260

Problem:
When bad mode happens, no pfn/far information is printed.
It get's problems to debug.

Solution:
1. Add far as parameter for bad_mode handler
2. Show pfn of all registers for bad_mode

Verify:
Local verified.

Change-Id: I4b0b457eff44ee717094ee8056f96ff16f111139
Signed-off-by: tao zeng <tao.zeng@amlogic.com>
arch/arm64/kernel/entry.S
arch/arm64/kernel/traps.c
arch/arm64/mm/fault.c

index 314e8a5..fead713 100644 (file)
@@ -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)
 
index 6296104..b2b036b 100644 (file)
@@ -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");
index 719108e..d97e502 100644 (file)
@@ -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 */