diff options
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 9636bace00e8..d3cbcd6bd985 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -119,6 +119,15 @@ static void decode_address(char *buf, unsigned long address) | |||
119 | return; | 119 | return; |
120 | } | 120 | } |
121 | 121 | ||
122 | /* | ||
123 | * Don't walk any of the vmas if we are oopsing, it has been known | ||
124 | * to cause problems - corrupt vmas (kernel crashes) cause double faults | ||
125 | */ | ||
126 | if (oops_in_progress) { | ||
127 | strcat(buf, "/* kernel dynamic memory (maybe user-space) */"); | ||
128 | return; | ||
129 | } | ||
130 | |||
122 | /* looks like we're off in user-land, so let's walk all the | 131 | /* looks like we're off in user-land, so let's walk all the |
123 | * mappings of all our processes and see if we can't be a whee | 132 | * mappings of all our processes and see if we can't be a whee |
124 | * bit more specific | 133 | * bit more specific |
@@ -515,6 +524,36 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) | |||
515 | break; | 524 | break; |
516 | /* External Memory Addressing Error */ | 525 | /* External Memory Addressing Error */ |
517 | case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): | 526 | case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): |
527 | if (ANOMALY_05000310) { | ||
528 | static unsigned long anomaly_rets; | ||
529 | |||
530 | if ((fp->pc >= (L1_CODE_START + L1_CODE_LENGTH - 512)) && | ||
531 | (fp->pc < (L1_CODE_START + L1_CODE_LENGTH))) { | ||
532 | /* | ||
533 | * A false hardware error will happen while fetching at | ||
534 | * the L1 instruction SRAM boundary. Ignore it. | ||
535 | */ | ||
536 | anomaly_rets = fp->rets; | ||
537 | goto traps_done; | ||
538 | } else if (fp->rets == anomaly_rets) { | ||
539 | /* | ||
540 | * While boundary code returns to a function, at the ret | ||
541 | * point, a new false hardware error might occur too based | ||
542 | * on tests. Ignore it too. | ||
543 | */ | ||
544 | goto traps_done; | ||
545 | } else if ((fp->rets >= (L1_CODE_START + L1_CODE_LENGTH - 512)) && | ||
546 | (fp->rets < (L1_CODE_START + L1_CODE_LENGTH))) { | ||
547 | /* | ||
548 | * If boundary code calls a function, at the entry point, | ||
549 | * a new false hardware error maybe happen based on tests. | ||
550 | * Ignore it too. | ||
551 | */ | ||
552 | goto traps_done; | ||
553 | } else | ||
554 | anomaly_rets = 0; | ||
555 | } | ||
556 | |||
518 | info.si_code = BUS_ADRERR; | 557 | info.si_code = BUS_ADRERR; |
519 | sig = SIGBUS; | 558 | sig = SIGBUS; |
520 | strerror = KERN_NOTICE HWC_x3(KERN_NOTICE); | 559 | strerror = KERN_NOTICE HWC_x3(KERN_NOTICE); |
@@ -976,12 +1015,12 @@ void dump_bfin_process(struct pt_regs *fp) | |||
976 | !((unsigned long)current & 0x3) && current->pid) { | 1015 | !((unsigned long)current & 0x3) && current->pid) { |
977 | verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); | 1016 | verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); |
978 | if (current->comm >= (char *)FIXED_CODE_START) | 1017 | if (current->comm >= (char *)FIXED_CODE_START) |
979 | verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n", | 1018 | verbose_printk(KERN_NOTICE "COMM=%s PID=%d", |
980 | current->comm, current->pid); | 1019 | current->comm, current->pid); |
981 | else | 1020 | else |
982 | verbose_printk(KERN_NOTICE "COMM= invalid\n"); | 1021 | verbose_printk(KERN_NOTICE "COMM= invalid"); |
983 | 1022 | ||
984 | printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu); | 1023 | printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu); |
985 | if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) | 1024 | if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) |
986 | verbose_printk(KERN_NOTICE | 1025 | verbose_printk(KERN_NOTICE |
987 | "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" | 1026 | "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" |