#include <asm/unwind.h>
#include <asm/tls.h>
#include <asm/system_misc.h>
-
+#include <linux/aee.h>
static const char *handler[]= {
"prefetch abort",
"data abort",
}
#endif
+void dump_stack(void)
+{
+ dump_backtrace(NULL, NULL);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
void show_stack(struct task_struct *tsk, unsigned long *sp)
{
dump_backtrace(NULL, tsk);
static int __die(const char *str, int err, struct pt_regs *regs)
{
struct task_struct *tsk = current;
+ unsigned long sp, stack;
static int die_counter;
int ret;
/* trap and error numbers are mostly meaningless on ARM */
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
if (ret == NOTIFY_STOP)
- return 1;
+ return ret;
print_modules();
__show_regs(regs);
TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
if (!user_mode(regs) || in_interrupt()) {
- dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
- THREAD_SIZE + (unsigned long)task_stack_page(tsk));
+ sp = regs->ARM_sp;
+ stack = (unsigned long)task_stack_page(tsk);
+ dump_mem(KERN_EMERG, "Stack: ", sp, ALIGN(sp, THREAD_SIZE));
+ if (sp < stack || (sp - stack) > THREAD_SIZE) {
+ printk(KERN_EMERG "Invalid sp[%lx] or stack address[%lx]\n", sp, stack);
+ dump_mem(KERN_EMERG, "Stack(backup) ", stack, THREAD_SIZE + stack);
+ }
dump_backtrace(regs, tsk);
dump_instr(KERN_EMERG, regs);
}
if (!die_nest_count)
/* Nest count reaches zero, release the lock. */
arch_spin_unlock(&die_lock);
- raw_local_irq_restore(flags);
+ /* not enable irq incase softirq many turn off msdc clock */
+ //raw_local_irq_restore(flags);
oops_exit();
if (in_interrupt())
return fn ? fn(regs, instr) : 1;
}
+volatile static void __user *prev_undefinstr_pc=0;
+volatile static int prev_undefinstr_counter=0;
+volatile static unsigned long prev_undefinstr_curr=0;
+
asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
{
+ struct thread_info *thread = current_thread_info();
+ int ret;
unsigned int instr;
siginfo_t info;
void __user *pc;
+ if (!user_mode(regs)) {
+ thread->cpu_excp++;
+ if (thread->cpu_excp == 1) {
+ thread->regs_on_excp = (void *)regs;
+ aee_excp_regs = (void*)regs;
+ }
+ if (thread->cpu_excp >= 2) {
+ aee_stop_nested_panic(regs);
+ }
+ }
+
pc = (void __user *)instruction_pointer(regs);
if (processor_mode(regs) == SVC_MODE) {
goto die_sig;
}
- if (call_undef_hook(regs, instr) == 0)
+ ret = call_undef_hook(regs, instr);
+ if (ret == 0) {
+ if (!user_mode(regs)) {
+ thread->cpu_excp--;
+ }
return;
+ }
die_sig:
#ifdef CONFIG_DEBUG_USER
}
#endif
+ /* Place the SIGILL ICache Invalidate after the Debugger Undefined-Instruction Solution. */
+ if ((processor_mode(regs) == USR_MODE) || (processor_mode(regs) == SVC_MODE)) {
+ /* Only do it for User-Space Application. */
+ printk("USR_MODE/SVC_MODE Undefined Instruction Address curr:%p pc=%p:%p\n",
+ (void *)current, (void *)pc, (void *)prev_undefinstr_pc);
+ if ((prev_undefinstr_pc != pc) || (prev_undefinstr_curr != (unsigned long)current)) {
+ /* If the current process or program counter is changed......renew the counter. */
+ printk("First Time Recovery curr:%p pc=%p:%p\n",
+ (void *)current, (void *)pc, (void *)prev_undefinstr_pc);
+ prev_undefinstr_pc = pc;
+ prev_undefinstr_curr = (unsigned long)current;
+ prev_undefinstr_counter = 0;
+ __cpuc_flush_icache_all();
+ flush_cache_all();
+ if (!user_mode(regs)) {
+ thread->cpu_excp--;
+ }
+ return;
+ }
+ else if(prev_undefinstr_counter < 1) {
+ printk("2nd Time Recovery curr:%p pc=%p:%p\n",
+ (void *)current, (void *)pc, (void *)prev_undefinstr_pc);
+ prev_undefinstr_counter++;
+ __cpuc_flush_icache_all();
+ flush_cache_all();
+ if (!user_mode(regs)) {
+ thread->cpu_excp--;
+ }
+ return;
+ }
+ prev_undefinstr_counter++;
+ if(prev_undefinstr_counter >= 4) {
+ /* 2=first time SigILL,3=2nd time NE-SigILL,4=3rd time CoreDump-SigILL */
+ prev_undefinstr_pc = 0;
+ prev_undefinstr_curr = 0;
+ prev_undefinstr_counter = 0;
+ }
+ printk("Go to ARM Notify Die curr:%p pc=%p:%p\n",
+ (void *)current, (void *)pc, (void *)prev_undefinstr_pc);
+ }
+
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_ILLOPC;
info.si_addr = pc;
arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
-}
+ }
asmlinkage void do_unexp_fiq (struct pt_regs *regs)
{