aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r--arch/blackfin/kernel/traps.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 56464cb8edf3..d3cbcd6bd985 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/traps.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author: Hamish Macdonald
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: uses S/W interrupt 15 for the system calls
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/bug.h> 7#include <linux/bug.h>
@@ -142,6 +119,15 @@ static void decode_address(char *buf, unsigned long address)
142 return; 119 return;
143 } 120 }
144 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
145 /* 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
146 * 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
147 * bit more specific 133 * bit more specific
@@ -538,6 +524,36 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
538 break; 524 break;
539 /* External Memory Addressing Error */ 525 /* External Memory Addressing Error */
540 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
541 info.si_code = BUS_ADRERR; 557 info.si_code = BUS_ADRERR;
542 sig = SIGBUS; 558 sig = SIGBUS;
543 strerror = KERN_NOTICE HWC_x3(KERN_NOTICE); 559 strerror = KERN_NOTICE HWC_x3(KERN_NOTICE);
@@ -642,7 +658,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
642 658
643/* 659/*
644 * Similar to get_user, do some address checking, then dereference 660 * Similar to get_user, do some address checking, then dereference
645 * Return true on sucess, false on bad address 661 * Return true on success, false on bad address
646 */ 662 */
647static bool get_instruction(unsigned short *val, unsigned short *address) 663static bool get_instruction(unsigned short *val, unsigned short *address)
648{ 664{
@@ -999,12 +1015,12 @@ void dump_bfin_process(struct pt_regs *fp)
999 !((unsigned long)current & 0x3) && current->pid) { 1015 !((unsigned long)current & 0x3) && current->pid) {
1000 verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); 1016 verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n");
1001 if (current->comm >= (char *)FIXED_CODE_START) 1017 if (current->comm >= (char *)FIXED_CODE_START)
1002 verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n", 1018 verbose_printk(KERN_NOTICE "COMM=%s PID=%d",
1003 current->comm, current->pid); 1019 current->comm, current->pid);
1004 else 1020 else
1005 verbose_printk(KERN_NOTICE "COMM= invalid\n"); 1021 verbose_printk(KERN_NOTICE "COMM= invalid");
1006 1022
1007 printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu); 1023 printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu);
1008 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)
1009 verbose_printk(KERN_NOTICE 1025 verbose_printk(KERN_NOTICE
1010 "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" 1026 "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n"
@@ -1163,7 +1179,7 @@ void show_regs(struct pt_regs *fp)
1163 if (fp->ipend & ~0x3F) { 1179 if (fp->ipend & ~0x3F) {
1164 for (i = 0; i < (NR_IRQS - 1); i++) { 1180 for (i = 0; i < (NR_IRQS - 1); i++) {
1165 if (!in_atomic) 1181 if (!in_atomic)
1166 spin_lock_irqsave(&irq_desc[i].lock, flags); 1182 raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
1167 1183
1168 action = irq_desc[i].action; 1184 action = irq_desc[i].action;
1169 if (!action) 1185 if (!action)
@@ -1178,7 +1194,7 @@ void show_regs(struct pt_regs *fp)
1178 verbose_printk("\n"); 1194 verbose_printk("\n");
1179unlock: 1195unlock:
1180 if (!in_atomic) 1196 if (!in_atomic)
1181 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 1197 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
1182 } 1198 }
1183 } 1199 }
1184 1200