Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=2ebcade590dcf822dcdadcc4f8f68efd3ff2e217
Commit:     2ebcade590dcf822dcdadcc4f8f68efd3ff2e217
Parent:     0ae53640b54f2c30e52044f7102ba08915b988a7
Author:     Robin Getz <[EMAIL PROTECTED]>
AuthorDate: Tue Oct 9 17:24:30 2007 +0800
Committer:  Bryan Wu <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 17:24:30 2007 +0800

    Blackfin arch: fix endless loop bug when a double fault happens
    
    Today when a double fault happens (exception during an exception
    handling event), we go into an endless loop, with nothing comming out
    the UART. With this patch, we actually see that we have commited a
    double fault event
    
    Signed-off-by: Robin Getz <[EMAIL PROTECTED]>
    Signed-off-by: Bryan Wu <[EMAIL PROTECTED]>
---
 arch/blackfin/kernel/traps.c      |    8 ++++
 arch/blackfin/mach-common/entry.S |   69 +++++++++++++++++++++++++++++--------
 2 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 1a8a5f1..ba68eb2 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -132,6 +132,14 @@ static int printk_address(unsigned long address)
 }
 #endif
 
+asmlinkage void double_fault_c(struct pt_regs *fp)
+{
+       printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
+       dump_bfin_regs(fp, (void *)fp->retx);
+       panic("Double Fault - unrecoverable event\n");
+
+}
+
 asmlinkage void trap_c(struct pt_regs *fp)
 {
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
diff --git a/arch/blackfin/mach-common/entry.S 
b/arch/blackfin/mach-common/entry.S
index 3feca05..e223936 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -29,21 +29,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-/*
- * 25-Dec-2004 - LG Soft India
- *     1. Fix in return_from_int, to make sure any pending
- *     system call in ILAT for this process to get
- *     executed, otherwise in case context switch happens,
- *     system call of first process (i.e in ILAT) will be
- *     carried forward to the switched process.
- *     2. Removed Constant references for the following
- *             a.  IPEND
- *             b.  EXCAUSE mask
- *             c.  PAGE Mask
- */
-
-/*
- * NOTE: This code handles signal-recognition, which happens every time
+/* NOTE: This code handles signal-recognition, which happens every time
  * after a timer-interrupt and after each system call.
  */
 
@@ -175,6 +161,13 @@ ENTRY(_ex_replaceable)
        nop;
 
 ENTRY(_ex_trap_c)
+       /* 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;
+
        /* 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.
@@ -220,6 +213,52 @@ ENTRY(_ex_trap_c)
        rtx;
 ENDPROC(_ex_trap_c)
 
+/* We just realized we got an exception, while we were processing a different
+ * exception. This is a unrecoverable event, so crash
+ */
+ENTRY(_double_fault)
+        /* Turn caches & protection off, to ensure we don't get any more
+         * double exceptions
+         */
+
+        P4.L = LO(IMEM_CONTROL);
+        P4.H = HI(IMEM_CONTROL);
+
+        R5 = [P4];              /* Control Register*/
+        BITCLR(R5,ENICPLB_P);
+        SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
+        .align 8;
+        [P4] = R5;
+        SSYNC;
+
+        P4.L = LO(DMEM_CONTROL);
+        P4.H = HI(DMEM_CONTROL);
+        R5 = [P4];
+        BITCLR(R5,ENDCPLB_P);
+        SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
+        .align 8;
+        [P4] = R5;
+        SSYNC;
+
+        /* Fix up the stack */
+        (R7:6,P5:4) = [sp++];
+        ASTAT = [sp++];
+        SP = EX_SCRATCH_REG;
+
+        /* We should be out of the exception stack, and back down into
+         * kernel or user space stack
+         */
+        SAVE_ALL_SYS
+
+        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
+        SP += -12;
+        call _double_fault_c;
+        SP += 12;
+.L_double_fault_panic:
+        JUMP .L_double_fault_panic
+
+ENDPROC(_double_fault)
+
 ENTRY(_exception_to_level5)
        SAVE_ALL_SYS
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to