diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-01-22 02:55:25 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-01-22 02:55:25 -0500 |
commit | 7755726fe90a8b253659756e6de68c1a55aa427f (patch) | |
tree | a3523fa77e07854db3b8089e3066a55ea997060c /arch/blackfin/kernel/traps.c | |
parent | 3bf127637e22ddf95e67e10a23c339cee3d52429 (diff) | |
parent | 92dcffb916d309aa01778bf8963a6932e4014d07 (diff) |
Merge commit 'v2.6.33-rc5' into next
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 78cb3d38f899..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" |
@@ -1140,7 +1179,7 @@ void show_regs(struct pt_regs *fp) | |||
1140 | if (fp->ipend & ~0x3F) { | 1179 | if (fp->ipend & ~0x3F) { |
1141 | for (i = 0; i < (NR_IRQS - 1); i++) { | 1180 | for (i = 0; i < (NR_IRQS - 1); i++) { |
1142 | if (!in_atomic) | 1181 | if (!in_atomic) |
1143 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 1182 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); |
1144 | 1183 | ||
1145 | action = irq_desc[i].action; | 1184 | action = irq_desc[i].action; |
1146 | if (!action) | 1185 | if (!action) |
@@ -1155,7 +1194,7 @@ void show_regs(struct pt_regs *fp) | |||
1155 | verbose_printk("\n"); | 1194 | verbose_printk("\n"); |
1156 | unlock: | 1195 | unlock: |
1157 | if (!in_atomic) | 1196 | if (!in_atomic) |
1158 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 1197 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
1159 | } | 1198 | } |
1160 | } | 1199 | } |
1161 | 1200 | ||