aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2009-06-21 22:02:16 -0400
committerMike Frysinger <vapier@gentoo.org>2009-09-16 21:28:28 -0400
commitae4f073c40bf677b03826262e6022b4a251fe437 (patch)
tree452c91be30a3970efbea5780d368945e7f63712c /arch/blackfin/kernel
parentd4b834c13940b5433d16ae3605794b3d74804348 (diff)
Blackfin: make EVT3->EVT5 lowering more robust wrt IPEND[4]
We handle many exceptions at EVT5 (hardware error level) so that we can catch exceptions in our exception handling code. Today - if the global interrupt enable bit (IPEND[4]) is set (interrupts disabled) our trap handling code goes into a infinite loop, since we need interrupts to be on to defer things to EVT5. Normal kernel code should not trigger this for any reason as IPEND[4] gets cleared early (when doing an interrupt context save) and the kernel stack there should be sane (or something much worse is happening in the system). But there have been a few times where this has happened, so this change makes sure we dump a proper crash message even when things have gone south. Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/asm-offsets.c1
-rw-r--r--arch/blackfin/kernel/traps.c19
2 files changed, 11 insertions, 9 deletions
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index b5df9459d6d5..8ad4f2c69961 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -145,6 +145,7 @@ int main(void)
145 DEFINE(PDA_EXBUF, offsetof(struct blackfin_pda, ex_buf)); 145 DEFINE(PDA_EXBUF, offsetof(struct blackfin_pda, ex_buf));
146 DEFINE(PDA_EXIMASK, offsetof(struct blackfin_pda, ex_imask)); 146 DEFINE(PDA_EXIMASK, offsetof(struct blackfin_pda, ex_imask));
147 DEFINE(PDA_EXSTACK, offsetof(struct blackfin_pda, ex_stack)); 147 DEFINE(PDA_EXSTACK, offsetof(struct blackfin_pda, ex_stack));
148 DEFINE(PDA_EXIPEND, offsetof(struct blackfin_pda, ex_ipend));
148#ifdef ANOMALY_05000261 149#ifdef ANOMALY_05000261
149 DEFINE(PDA_LFRETX, offsetof(struct blackfin_pda, last_cplb_fault_retx)); 150 DEFINE(PDA_LFRETX, offsetof(struct blackfin_pda, last_cplb_fault_retx));
150#endif 151#endif
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index bf2b2d1f8ae5..fccf741ed3b5 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -267,11 +267,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
267 * double faults if the stack has become corrupt 267 * double faults if the stack has become corrupt
268 */ 268 */
269 269
270#ifndef CONFIG_KGDB
271 /* IPEND is skipped if KGDB isn't enabled (see entry code) */
272 fp->ipend = bfin_read_IPEND();
273#endif
274
275 /* trap_c() will be called for exceptions. During exceptions 270 /* trap_c() will be called for exceptions. During exceptions
276 * processing, the pc value should be set with retx value. 271 * processing, the pc value should be set with retx value.
277 * With this change we can cleanup some code in signal.c- TODO 272 * With this change we can cleanup some code in signal.c- TODO
@@ -1116,10 +1111,16 @@ void show_regs(struct pt_regs *fp)
1116 1111
1117 verbose_printk(KERN_NOTICE "%s", linux_banner); 1112 verbose_printk(KERN_NOTICE "%s", linux_banner);
1118 1113
1119 verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", 1114 verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted());
1120 print_tainted()); 1115 verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n",
1121 verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", 1116 (long)fp->seqstat, fp->ipend, cpu_pda[smp_processor_id()].ex_imask, fp->syscfg);
1122 (long)fp->seqstat, fp->ipend, fp->syscfg); 1117 if (fp->ipend & EVT_IRPTEN)
1118 verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n");
1119 if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 |
1120 EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR)))
1121 verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n");
1122 if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14)))
1123 verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n");
1123 if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { 1124 if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
1124 verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", 1125 verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n",
1125 (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); 1126 (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);