aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/fault.c')
-rw-r--r--arch/arm/mm/fault.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index bc0e1d8..6f66c0e 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -24,6 +24,10 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
+#if defined(CONFIG_MACH_Q1_BD)
+#include <mach/sec_debug.h>
+#endif
+
#include "fault.h"
/*
@@ -162,6 +166,29 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
do_exit(SIGKILL);
}
+#if defined(CONFIG_MACH_Q1_BD)
+/*
+ * This function can be used while current pointer is invalid.
+ */
+static void
+__do_kernel_fault_safe(struct mm_struct *mm, unsigned long addr,
+ unsigned int fsr, struct pt_regs *regs)
+{
+ static char buf[64] = "__do_kernel_fault_safe";
+
+ printk(KERN_ALERT
+ "Unable to handle kernel %s at virtual address %08lx\n",
+ (addr < PAGE_SIZE) ? "NULL pointer dereference" :
+ "paging request", addr);
+
+ printk(KERN_ALERT "current is %p\n", current);
+
+ __show_regs(regs);
+
+ sec_debug_panic_handler_safe(buf);
+}
+#endif
+
/*
* Something tried to access memory that isn't in our memory map..
* User mode accesses just cause a SIGSEGV
@@ -283,7 +310,17 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
return 0;
tsk = current;
- mm = tsk->mm;
+#if defined(CONFIG_MACH_Q1_BD)
+ /*
+ * If current pointer is NULL, infinite abort can occur.
+ * It make us get correct debug information in the situation.
+ */
+ if (!tsk) {
+ __do_kernel_fault_safe(NULL, addr, fsr, regs);
+ return 0;
+ }
+#endif
+ mm = tsk->mm;
/*
* If we're in an interrupt or have no user