From: Mike Frysinger <vapier@gentoo.org>
To: linux-kernel@vger.kernel.org
Cc: uclinux-dist-devel@blackfin.uclinux.org,
Robin Getz <robin.getz@analog.com>
Subject: [PATCH 04/72] Blackfin: make EVT3->EVT5 lowering more robust wrt IPEND[4]
Date: Mon, 14 Sep 2009 16:07:08 -0400 [thread overview]
Message-ID: <1252958896-25150-5-git-send-email-vapier@gentoo.org> (raw)
In-Reply-To: <1252958896-25150-1-git-send-email-vapier@gentoo.org>
From: Robin Getz <robin.getz@analog.com>
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>
---
arch/blackfin/include/asm/pda.h | 1 +
arch/blackfin/kernel/asm-offsets.c | 1 +
arch/blackfin/kernel/traps.c | 19 ++++----
arch/blackfin/mach-common/entry.S | 86 ++++++++++++++++++++++-------------
4 files changed, 66 insertions(+), 41 deletions(-)
diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h
index b42555c..69b96b4 100644
--- a/arch/blackfin/include/asm/pda.h
+++ b/arch/blackfin/include/asm/pda.h
@@ -50,6 +50,7 @@ struct blackfin_pda { /* Per-processor Data Area */
unsigned long ex_optr;
unsigned long ex_buf[4];
unsigned long ex_imask; /* Saved imask from exception */
+ unsigned long ex_ipend; /* Saved IPEND from exception */
unsigned long *ex_stack; /* Exception stack space */
#ifdef ANOMALY_05000261
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index b5df945..8ad4f2c 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -145,6 +145,7 @@ int main(void)
DEFINE(PDA_EXBUF, offsetof(struct blackfin_pda, ex_buf));
DEFINE(PDA_EXIMASK, offsetof(struct blackfin_pda, ex_imask));
DEFINE(PDA_EXSTACK, offsetof(struct blackfin_pda, ex_stack));
+ DEFINE(PDA_EXIPEND, offsetof(struct blackfin_pda, ex_ipend));
#ifdef ANOMALY_05000261
DEFINE(PDA_LFRETX, offsetof(struct blackfin_pda, last_cplb_fault_retx));
#endif
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index bf2b2d1..fccf741 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)
* double faults if the stack has become corrupt
*/
-#ifndef CONFIG_KGDB
- /* IPEND is skipped if KGDB isn't enabled (see entry code) */
- fp->ipend = bfin_read_IPEND();
-#endif
-
/* trap_c() will be called for exceptions. During exceptions
* processing, the pc value should be set with retx value.
* With this change we can cleanup some code in signal.c- TODO
@@ -1116,10 +1111,16 @@ void show_regs(struct pt_regs *fp)
verbose_printk(KERN_NOTICE "%s", linux_banner);
- verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n",
- print_tainted());
- verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n",
- (long)fp->seqstat, fp->ipend, fp->syscfg);
+ verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted());
+ verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n",
+ (long)fp->seqstat, fp->ipend, cpu_pda[smp_processor_id()].ex_imask, fp->syscfg);
+ if (fp->ipend & EVT_IRPTEN)
+ verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n");
+ if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 |
+ EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR)))
+ verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n");
+ if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14)))
+ verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n");
if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n",
(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index fb1795d..4c07fcb 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -301,25 +301,31 @@ ENTRY(_ex_replaceable)
nop;
ENTRY(_ex_trap_c)
+ /* The only thing that has been saved in this context is
+ * (R7:6,P5:4), ASTAT & SP - don't use anything else
+ */
+
+ GET_PDA(p5, r6);
+
/* Make sure we are not in a double fault */
p4.l = lo(IPEND);
p4.h = hi(IPEND);
r7 = [p4];
CC = BITTST (r7, 5);
if CC jump _double_fault;
+ [p5 + PDA_EXIPEND] = r7;
/* Call C code (trap_c) to handle the exception, which most
* likely involves sending a signal to the current process.
* To avoid double faults, lower our priority to IRQ5 first.
*/
- P5.h = _exception_to_level5;
- P5.l = _exception_to_level5;
+ r7.h = _exception_to_level5;
+ r7.l = _exception_to_level5;
p4.l = lo(EVT5);
p4.h = hi(EVT5);
- [p4] = p5;
+ [p4] = r7;
csync;
- GET_PDA(p5, r6);
#ifndef CONFIG_DEBUG_DOUBLEFAULT
/*
@@ -349,8 +355,7 @@ ENTRY(_ex_trap_c)
BITCLR(r6, SYSCFG_SSSTEP_P);
SYSCFG = r6;
- /* Disable all interrupts, but make sure level 5 is enabled so
- * we can switch to that level. Save the old mask. */
+ /* Save the current IMASK, since we change in order to jump to level 5 */
cli r6;
[p5 + PDA_EXIMASK] = r6;
@@ -358,9 +363,21 @@ ENTRY(_ex_trap_c)
p4.h = hi(SAFE_USER_INSTRUCTION);
retx = p4;
+ /* Disable all interrupts, but make sure level 5 is enabled so
+ * we can switch to that level.
+ */
r6 = 0x3f;
sti r6;
+ /* In case interrupts are disabled IPEND[4] (global interrupt disable bit)
+ * clear it (re-enabling interrupts again) by the special sequence of pushing
+ * RETI onto the stack. This way we can lower ourselves to IVG5 even if the
+ * exception was taken after the interrupt handler was called but before it
+ * got a chance to enable global interrupts itself.
+ */
+ [--sp] = reti;
+ sp += 4;
+
raise 5;
jump.s _bfin_return_from_exception;
ENDPROC(_ex_trap_c)
@@ -420,47 +437,52 @@ ENDPROC(_double_fault)
ENTRY(_exception_to_level5)
SAVE_ALL_SYS
- GET_PDA(p4, r7); /* Fetch current PDA */
- r6 = [p4 + PDA_RETX];
+ GET_PDA(p5, r7); /* Fetch current PDA */
+ r6 = [p5 + PDA_RETX];
[sp + PT_PC] = r6;
- r6 = [p4 + PDA_SYSCFG];
+ r6 = [p5 + PDA_SYSCFG];
[sp + PT_SYSCFG] = r6;
- /* Restore interrupt mask. We haven't pushed RETI, so this
- * doesn't enable interrupts until we return from this handler. */
- r6 = [p4 + PDA_EXIMASK];
- sti r6;
-
/* Restore the hardware error vector. */
- P5.h = _evt_ivhw;
- P5.l = _evt_ivhw;
+ r7.h = _evt_ivhw;
+ r7.l = _evt_ivhw;
p4.l = lo(EVT5);
p4.h = hi(EVT5);
- [p4] = p5;
+ [p4] = r7;
csync;
- p2.l = lo(IPEND);
- p2.h = hi(IPEND);
- csync;
- r0 = [p2]; /* Read current IPEND */
- [sp + PT_IPEND] = r0; /* Store IPEND */
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+ /* Now that we have the hardware error vector programmed properly
+ * we can re-enable interrupts (IPEND[4]), so if the _trap_c causes
+ * another hardware error, we can catch it (self-nesting).
+ */
+ [--sp] = reti;
+ sp += 4;
+#endif
+
+ r7 = [p5 + PDA_EXIPEND] /* Read the IPEND from the Exception state */
+ [sp + PT_IPEND] = r7; /* Store IPEND onto the stack */
r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
SP += -12;
call _trap_c;
SP += 12;
-#ifdef CONFIG_DEBUG_DOUBLEFAULT
- /* Grab ILAT */
- p2.l = lo(ILAT);
- p2.h = hi(ILAT);
- r0 = [p2];
- r1 = 0x20; /* Did I just cause anther HW error? */
- r0 = r0 & r1;
- CC = R0 == R1;
- if CC JUMP _double_fault;
-#endif
+ /* If interrupts were off during the exception (IPEND[4] = 1), turn them off
+ * before we return.
+ */
+ CC = BITTST(r7, EVT_IRPTEN_P)
+ if !CC jump 1f;
+ /* this will load a random value into the reti register - but that is OK,
+ * since we do restore it to the correct value in the 'RESTORE_ALL_SYS' macro
+ */
+ sp += -4;
+ reti = [sp++];
+1:
+ /* restore the interrupt mask (IMASK) */
+ r6 = [p5 + PDA_EXIMASK];
+ sti r6;
call _ret_from_exception;
RESTORE_ALL_SYS
--
1.6.4.2
next prev parent reply other threads:[~2009-09-14 20:08 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-14 20:07 [PATCH 00/72] Blackfin updates for 2.6.32 Mike Frysinger
2009-09-14 20:07 ` [PATCH 01/72] Blackfin: bf537-stamp: update ADP5588 header name Mike Frysinger
2009-09-14 20:07 ` [PATCH 02/72] Blackfin: bf537-stamp: declare SPI IRQ resources Mike Frysinger
2009-09-14 20:07 ` [PATCH 03/72] Blackfin: bf537-stamp: add resources for AD1938 audio card Mike Frysinger
2009-09-14 20:07 ` Mike Frysinger [this message]
2009-09-14 20:07 ` [PATCH 05/72] Blackfin: checkpatch --file arch/blackfin/kernel/ipipe.c Mike Frysinger
2009-09-14 20:07 ` [PATCH 06/72] Blackfin: fix misnomer of some I-pipe helpers Mike Frysinger
2009-09-14 20:07 ` [PATCH 07/72] Blackfin: export show_stack() to modules Mike Frysinger
2009-09-14 20:07 ` [PATCH 08/72] Blackfin: allow high priority domains to preempt schedule_tail() Mike Frysinger
2009-09-14 20:07 ` [PATCH 09/72] Blackfin: use generic name for EVT14 handler Mike Frysinger
2009-09-14 20:07 ` [PATCH 10/72] Blackfin: reuse evt_evt14 handler to perform irqtail epilogue Mike Frysinger
2009-09-14 20:07 ` [PATCH 11/72] Blackfin: allow EVT5 to preempt irqtail prologue (CONFIG_DEBUG_HWERR) Mike Frysinger
2009-09-14 20:07 ` [PATCH 12/72] Blackfin: document __ipipe_call_irqtail Mike Frysinger
2009-09-14 20:07 ` [PATCH 13/72] Blackfin: sanitize manual control of IPEND[4] Mike Frysinger
2009-09-14 20:07 ` [PATCH 14/72] Blackfin: inline I-pipe bypass code in ret_from_exception Mike Frysinger
2009-09-14 20:07 ` [PATCH 15/72] Blackfin: cleanup traps decode_address() a bit Mike Frysinger
2009-09-14 20:07 ` [PATCH 16/72] Blackfin: convert ptrace to new memory functions Mike Frysinger
2009-09-14 20:07 ` [PATCH 17/72] Blackfin: reject outdated/unused/wrong relocation types Mike Frysinger
2009-09-14 20:07 ` [PATCH 18/72] Blackfin: cleanup printk() usage in module code Mike Frysinger
2009-09-14 20:07 ` [PATCH 19/72] Blackfin: convert malloc()/memset() to zalloc() " Mike Frysinger
2009-09-14 20:07 ` [PATCH 20/72] Blackfin: cleanup module section checking Mike Frysinger
2009-09-14 20:07 ` [PATCH 21/72] Blackfin: fix module reloc handling for all memory regions Mike Frysinger
2009-09-14 20:07 ` [PATCH 22/72] Blackfin: clean up early memory setup code Mike Frysinger
2009-09-14 20:07 ` [PATCH 23/72] Blackfin: rename PCF8574 driver config Mike Frysinger
2009-09-14 20:07 ` [PATCH 24/72] Blackfin: unify duplicated SMP checks in L2 cache kconfig Mike Frysinger
2009-09-14 20:07 ` [PATCH 25/72] Blackfin: push SRAM locks down into related ifdefs Mike Frysinger
2009-09-14 20:07 ` [PATCH 26/72] Blackfin: add support for common FDPIC ptrace requests Mike Frysinger
2009-09-14 20:07 ` [PATCH 27/72] Blackfin: add an early shadow console Mike Frysinger
2009-09-14 20:07 ` [PATCH 28/72] Blackfin: catch hardware errors earlier during booting Mike Frysinger
2009-09-14 20:07 ` [PATCH 29/72] Blackfin: fix BF548 UART0 DMA IRQ translation Mike Frysinger
2009-09-14 20:07 ` [PATCH 30/72] Blackfin: bf538: add bfin_clear_PPI_STATUS() helper Mike Frysinger
2009-09-14 20:07 ` [PATCH 31/72] Blackfin: bf533-stamp: add resources for mmc_spi card Mike Frysinger
2009-09-14 20:07 ` [PATCH 32/72] Blackfin: do not try displaying the end of the stack Mike Frysinger
2009-09-14 20:07 ` [PATCH 33/72] Blackfin: bf537-stamp: update AD714x resources Mike Frysinger
2009-09-14 20:07 ` [PATCH 34/72] Blackfin: clean up duplicate I2C device type definitions Mike Frysinger
2009-09-14 20:07 ` [PATCH 35/72] Blackfin: fix MPU handling of invalid memory accesses Mike Frysinger
2009-09-14 20:07 ` [PATCH 36/72] Blackfin: bf533-stamp: fix typo in SPI frequency for ad1836 codec Mike Frysinger
2009-09-14 20:07 ` [PATCH 37/72] Blackfin: improve double fault debug handling Mike Frysinger
2009-09-14 20:07 ` [PATCH 38/72] Blackfin: bf537-stamp: drop ATA interrupt probe workaround Mike Frysinger
2009-09-14 20:07 ` [PATCH 39/72] Blackfin: convert boards to use platform data with smc91x Mike Frysinger
2009-09-14 20:07 ` [PATCH 40/72] Blackfin: drop unused MMR defines that only cause bad code to be written Mike Frysinger
2009-09-14 20:07 ` [PATCH 41/72] Blackfin: cm-bf527/bf537-stamp: fix dm9000 resources Mike Frysinger
2009-09-14 20:07 ` [PATCH 42/72] Blackfin: bf548-ezkit: fix incorrect LCD size parameters Mike Frysinger
2009-09-14 20:07 ` [PATCH 43/72] Blackfin: fix read buffer overflow Mike Frysinger
2009-09-14 20:07 ` [PATCH 44/72] Blackfin: bf538-ezkit: add resources for parallel flash Mike Frysinger
2009-09-14 20:07 ` [PATCH 45/72] Blackfin: update anomaly lists Mike Frysinger
2009-09-14 20:07 ` [PATCH 46/72] Blackfin: bf537-stamp: update ad1836 resources Mike Frysinger
2009-09-14 20:07 ` [PATCH 47/72] Blackfin: cleanup sync handling when enabling/disabling cplbs Mike Frysinger
2009-09-14 20:07 ` [PATCH 48/72] Blackfin: SMP port does not yet support cpu frequency scaling Mike Frysinger
2009-09-14 20:07 ` [PATCH 49/72] Blackfin: fix BF522/BF523 max VCO mixup Mike Frysinger
2009-09-14 20:07 ` [PATCH 50/72] Blackfin: do not trace the exception handler Mike Frysinger
2009-09-14 20:07 ` [PATCH 51/72] Blackfin: drop board resources for dead devices (pbx/ad9960) Mike Frysinger
2009-09-14 20:07 ` [PATCH 52/72] Blackfin: punt dead cache locking code Mike Frysinger
2009-09-14 20:07 ` [PATCH 53/72] Blackfin: delete '-spi' suffix in ad1836/ad1938 driver name Mike Frysinger
2009-09-14 20:07 ` [PATCH 54/72] Blackfin: optimize fixed code handling for the most common case Mike Frysinger
2009-09-14 20:07 ` [PATCH 55/72] Blackfin: handle the core timer interrupt with handle_percpu_irq on SMP Mike Frysinger
2009-09-14 20:08 ` [PATCH 56/72] Blackfin: Fix link errors with binutils 2.19 and GCC 4.3 Mike Frysinger
2009-09-14 20:08 ` [PATCH 57/72] Blackfin: remove useless duplicated assignment in gpio code Mike Frysinger
2009-09-14 20:08 ` [PATCH 58/72] Blackfin: use raw_smp_processor_id() in exception code Mike Frysinger
2009-09-14 20:08 ` [PATCH 59/72] Blackfin: fix spelling in a few comments Mike Frysinger
2009-09-14 20:08 ` [PATCH 60/72] Blackfin: workaround anomaly 05000283 Mike Frysinger
2009-09-14 20:08 ` [PATCH 61/72] Blackfin: add some isram-driver self tests Mike Frysinger
2009-09-14 20:08 ` [PATCH 62/72] Blackfin: bf537-stamp: add adp5588 gpio resources Mike Frysinger
2009-09-14 20:08 ` [PATCH 63/72] Blackfin: fix typo in isram_write() Mike Frysinger
2009-09-14 20:08 ` [PATCH 64/72] Blackfin: fix BF54x SPI CS resources Mike Frysinger
2009-09-14 20:08 ` [PATCH 65/72] Blackfin: use KERN_ALERT in all kgdb_test output Mike Frysinger
2009-09-14 20:08 ` [PATCH 66/72] Blackfin: add ICPLB coverage for async banks Mike Frysinger
2009-09-14 20:08 ` [PATCH 67/72] Blackfin: increase default async timings for parallel flashes Mike Frysinger
2009-09-14 20:08 ` [PATCH 68/72] Blackfin: bf538-ezkit: add SPI IRQ resources Mike Frysinger
2009-09-14 20:08 ` [PATCH 69/72] Blackfin: cm-bf537u: split board from cm-bf537e Mike Frysinger
2009-09-14 20:08 ` [PATCH 70/72] Blackfin: update cm board resources Mike Frysinger
2009-09-14 20:08 ` [PATCH 71/72] Blackfin: update ftrace_push_return_trace() breakage Mike Frysinger
2009-09-14 20:08 ` [PATCH 72/72] Blackfin: swap clocksource ratings for gptimer/cycles Mike Frysinger
2009-09-14 20:50 ` [PATCH 00/72] Blackfin updates for 2.6.32 Daniel Walker
2009-09-14 20:57 ` Mike Frysinger
2009-09-14 21:04 ` Daniel Walker
2009-09-14 21:07 ` Mike Frysinger
2009-09-14 21:21 ` Daniel Walker
2009-09-14 22:17 ` Mike Frysinger
2009-09-14 22:36 ` Daniel Walker
2009-09-16 2:54 ` Mike Frysinger
2009-09-16 2:56 ` Mike Frysinger
2009-09-16 3:06 ` Daniel Walker
2009-09-16 3:21 ` Mike Frysinger
2009-09-16 3:59 ` Daniel Walker
2009-09-16 4:13 ` Mike Frysinger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1252958896-25150-5-git-send-email-vapier@gentoo.org \
--to=vapier@gentoo.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robin.getz@analog.com \
--cc=uclinux-dist-devel@blackfin.uclinux.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®