linux-mips
[Top] [All Lists]

[PATCH 1/3] [MIPS] lockdep: fix TRACE_IRQFLAGS_SUPPORT

To: linux-mips@linux-mips.org
Subject: [PATCH 1/3] [MIPS] lockdep: fix TRACE_IRQFLAGS_SUPPORT
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Tue, 26 Sep 2006 23:43:40 +0900 (JST)
Cc: ralf@linux-mips.org, mingo@redhat.com
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
In handle_sys and its variants, we must reload some registers which
might be clobbered by trace_hardirqs_on().
Also we must make sure trace_hardirqs_on() called in kernel level (not
exception level).

This is a patch againt linux-mips.org git tree.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>

 arch/mips/kernel/scall32-o32.S |   13 +------------
 arch/mips/kernel/scall64-64.S  |    2 +-
 arch/mips/kernel/scall64-n32.S |    2 +-
 arch/mips/kernel/scall64-o32.S |    2 +-
 include/asm-mips/irqflags.h    |   25 +++++++++++++++++++++++++
 5 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index e717851..61362e6 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -28,18 +28,7 @@ #define MAX_SYSCALL_NO       __NR_O32_Linux + 
 NESTED(handle_sys, PT_SIZE, sp)
        .set    noat
        SAVE_SOME
-#ifdef CONFIG_TRACE_IRQFLAGS
-       TRACE_IRQS_ON
-#ifdef CONFIG_64BIT
-       LONG_L  $8, PT_R8(sp)
-       LONG_L  $9, PT_R9(sp)
-#endif
-       LONG_L  $7, PT_R7(sp)
-       LONG_L  $6, PT_R6(sp)
-       LONG_L  $5, PT_R5(sp)
-       LONG_L  $4, PT_R4(sp)
-       LONG_L  $2, PT_R2(sp)
-#endif
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
 
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 4c22d0b..6c7b5ed 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -34,7 +34,7 @@ #if !defined(CONFIG_MIPS32_O32) && !defi
         */
        .set    noat
        SAVE_SOME
-       TRACE_IRQS_ON
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
 #endif
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index f25c2a2..6d9f187 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -33,7 +33,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 #ifndef CONFIG_MIPS32_O32
        .set    noat
        SAVE_SOME
-       TRACE_IRQS_ON
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
 #endif
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 288ee4a..2e6d067 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -28,7 +28,7 @@ #include <asm/sysmips.h>
 NESTED(handle_sys, PT_SIZE, sp)
        .set    noat
        SAVE_SOME
-       TRACE_IRQS_ON
+       TRACE_IRQS_ON_RELOAD
        STI
        .set    at
        ld      t1, PT_EPC(sp)          # skip syscall on return
diff --git a/include/asm-mips/irqflags.h b/include/asm-mips/irqflags.h
index 43ca09a..46bf5de 100644
--- a/include/asm-mips/irqflags.h
+++ b/include/asm-mips/irqflags.h
@@ -213,12 +213,37 @@ #endif
  * Do the CPU's IRQ-state tracing from assembly code.
  */
 #ifdef CONFIG_TRACE_IRQFLAGS
+/* Reload some registers clobbered by trace_hardirqs_on */
+#ifdef CONFIG_64BIT
+# define TRACE_IRQS_RELOAD_REGS                                                
\
+       LONG_L  $11, PT_R11(sp);                                        \
+       LONG_L  $10, PT_R10(sp);                                        \
+       LONG_L  $9, PT_R9(sp);                                          \
+       LONG_L  $8, PT_R8(sp);                                          \
+       LONG_L  $7, PT_R7(sp);                                          \
+       LONG_L  $6, PT_R6(sp);                                          \
+       LONG_L  $5, PT_R5(sp);                                          \
+       LONG_L  $4, PT_R4(sp);                                          \
+       LONG_L  $2, PT_R2(sp)
+#else
+# define TRACE_IRQS_RELOAD_REGS                                                
\
+       LONG_L  $7, PT_R7(sp);                                          \
+       LONG_L  $6, PT_R6(sp);                                          \
+       LONG_L  $5, PT_R5(sp);                                          \
+       LONG_L  $4, PT_R4(sp);                                          \
+       LONG_L  $2, PT_R2(sp)
+#endif
 # define TRACE_IRQS_ON                                                 \
+       CLI;    /* make sure trace_hardirqs_on() is called in kernel level */ \
        jal     trace_hardirqs_on
+# define TRACE_IRQS_ON_RELOAD                                          \
+       TRACE_IRQS_ON;                                                  \
+       TRACE_IRQS_RELOAD_REGS
 # define TRACE_IRQS_OFF                                                        
\
        jal     trace_hardirqs_off
 #else
 # define TRACE_IRQS_ON
+# define TRACE_IRQS_ON_RELOAD
 # define TRACE_IRQS_OFF
 #endif
 

<Prev in Thread] Current Thread [Next in Thread>