sparc64: Make %pil level 15 a pseudo-NMI.
authorDavid S. Miller <davem@davemloft.net>
Mon, 24 Nov 2008 05:55:29 +0000 (21:55 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 4 Dec 2008 17:17:02 +0000 (09:17 -0800)
So that we can profile code even in a local_irq_disable() section,
only write 14 (instead of 15) into the %pil register to disable IRQs.

This allows PIL level 15 to serve as a pseudo NMI.

Signed-off-by: David S. Miller <davem@davemloft.net>
12 files changed:
arch/sparc/include/asm/irqflags_64.h
arch/sparc/include/asm/pil.h
arch/sparc/include/asm/ttable.h
arch/sparc/mm/ultra.S
arch/sparc64/kernel/cherrs.S
arch/sparc64/kernel/head.S
arch/sparc64/kernel/hvtramp.S
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/spiterrs.S
arch/sparc64/kernel/sun4v_ivec.S
arch/sparc64/kernel/traps.c
arch/sparc64/kernel/ttable.S

index bb42e59162aab85829566a369255a55ce67180aa..8b49bf920df3b11a1d7d9b661891c5d0918a11de 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef _ASM_IRQFLAGS_H
 #define _ASM_IRQFLAGS_H
 
+#include <asm/pil.h>
+
 #ifndef __ASSEMBLY__
 
 static inline unsigned long __raw_local_save_flags(void)
@@ -40,9 +42,9 @@ static inline void raw_local_irq_restore(unsigned long flags)
 static inline void raw_local_irq_disable(void)
 {
        __asm__ __volatile__(
-               "wrpr   15, %%pil"
+               "wrpr   %0, %%pil"
                : /* no outputs */
-               : /* no inputs */
+               : "i" (PIL_NORMAL_MAX)
                : "memory"
        );
 }
index 71819bb943fc7e863f0a82cd8e4ff11f2b324c74..d573820c0ff4fc9bc766687174acdde78d664700 100644 (file)
  *
  * In fact any XCALL which has to etrap/rtrap has a problem because
  * it is difficult to prevent rtrap from running BH's, and that would
- * need to be done if the XCALL arrived while %pil==15.
+ * need to be done if the XCALL arrived while %pil==PIL_NORMAL_MAX.
+ *
+ * Finally, in order to handle profiling events even when a
+ * local_irq_disable() is in progress, we only disable up to level 14
+ * interrupts.  Profile counter overflow interrupts arrive at level
+ * 15.
  */
 #define PIL_SMP_CALL_FUNC      1
 #define PIL_SMP_RECEIVE_SIGNAL 2
@@ -18,5 +23,7 @@
 #define PIL_SMP_CTX_NEW_VERSION        4
 #define PIL_DEVICE_IRQ         5
 #define PIL_SMP_CALL_FUNC_SNGL 6
+#define PIL_NORMAL_MAX         14
+#define PIL_NMI                        15
 
 #endif /* !(_SPARC64_PIL_H) */
index 5708ba2719fb07e666cef4a0cc1e1cccf597d14d..bb2c0770a6ac4d879d0efffaab8d850283fd45eb 100644 (file)
@@ -2,6 +2,7 @@
 #define _SPARC64_TTABLE_H
 
 #include <asm/utrap.h>
+#include <asm/pil.h>
 
 #ifdef __ASSEMBLY__
 #include <asm/thread_info.h>
 
 #define TRAP_IRQ(routine, level)                       \
        rdpr    %pil, %g2;                              \
-       wrpr    %g0, 15, %pil;                          \
+       wrpr    %g0, PIL_NORMAL_MAX, %pil;              \
        sethi   %hi(1f-4), %g7;                         \
        ba,pt   %xcc, etrap_irq;                        \
         or     %g7, %lo(1f-4), %g7;                    \
 
 #define TRAP_IRQ(routine, level)                       \
        rdpr    %pil, %g2;                              \
-       wrpr    %g0, 15, %pil;                          \
+       wrpr    %g0, PIL_NORMAL_MAX, %pil;              \
        ba,pt   %xcc, etrap_irq;                        \
         rd     %pc, %g7;                               \
        mov     level, %o0;                             \
 
 #endif
 
+#define TRAP_NMI_IRQ(routine, level)                   \
+       rdpr    %pil, %g2;                              \
+       wrpr    %g0, PIL_NMI, %pil;                     \
+       ba,pt   %xcc, etrap_irq;                        \
+        rd     %pc, %g7;                               \
+       mov     level, %o0;                             \
+       call    routine;                                \
+        add    %sp, PTREGS_OFF, %o1;                   \
+       ba,a,pt %xcc, rtrap_irq;
+
 #define TRAP_IVEC TRAP_NOSAVE(do_ivec)
 
 #define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
index e4c146f7c7e9aa0914124d60a183a53db80c453f..80c788ec7c321ef7738b005eb57f00e2f89e13fd 100644 (file)
@@ -466,7 +466,7 @@ xcall_sync_tick:
        .previous
 
        rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        sethi           %hi(109f), %g7
        b,pt            %xcc, etrap_irq
 109:    or             %g7, %lo(109b), %g7
@@ -688,7 +688,7 @@ xcall_kgdb_capture:
        .previous
 
        rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        sethi           %hi(109f), %g7
        ba,pt           %xcc, etrap_irq
 109:    or             %g7, %lo(109b), %g7
index 89afebd7eca08ef7f00343a4a4484b699242373f..4ee1ad420862d425cff03ba7aad8e395fcb75907 100644 (file)
@@ -102,7 +102,7 @@ cheetah_plus_dcpe_trap_vector:
        .type           do_cheetah_plus_data_parity,#function
 do_cheetah_plus_data_parity:
        rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        ba,pt           %xcc, etrap_irq
         rd             %pc, %g7
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -144,7 +144,7 @@ cheetah_plus_icpe_trap_vector:
        .type           do_cheetah_plus_insn_parity,#function
 do_cheetah_plus_insn_parity:
        rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        ba,pt           %xcc, etrap_irq
         rd             %pc, %g7
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -492,7 +492,7 @@ cheetah_fast_ecc:
        .type           c_fast_ecc,#function
 c_fast_ecc:
        rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        ba,pt           %xcc, etrap_irq
         rd             %pc, %g7
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -528,7 +528,7 @@ cheetah_cee:
        .type           c_cee,#function
 c_cee:
        rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        ba,pt           %xcc, etrap_irq
         rd             %pc, %g7
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -564,7 +564,7 @@ cheetah_deferred_trap:
        .type           c_deferred,#function
 c_deferred:
        rdpr            %pil, %g2
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        ba,pt           %xcc, etrap_irq
         rd             %pc, %g7
 #ifdef CONFIG_TRACE_IRQFLAGS
index 353226fa023991240653fadf8504b958dc4529ae..45830c35fc6dd75c079c4cefbd25d53ce14d4099 100644 (file)
@@ -706,7 +706,7 @@ setup_trap_table:
        andn    %l0, PSTATE_IE, %o1
        wrpr    %o1, 0x0, %pstate
        rdpr    %pil, %l1
-       wrpr    %g0, 15, %pil
+       wrpr    %g0, PIL_NORMAL_MAX, %pil
 
        /* Make the firmware call to jump over to the Linux trap table.  */
        sethi   %hi(is_sun4v), %o0
index 0236c43772faf50385fd5348fb4f16d34dfcc98b..9365432904d64eb7ef017506991eab7bcbea4f2f 100644 (file)
@@ -1,6 +1,6 @@
 /* hvtramp.S: Hypervisor start-cpu trampoline code.
  *
- * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
  */
 
 #include <linux/init.h>
@@ -14,6 +14,7 @@
 #include <asm/ptrace.h>
 #include <asm/head.h>
 #include <asm/asi.h>
+#include <asm/pil.h>
 
        __CPUINIT
        .align          8
@@ -32,7 +33,7 @@
         */
 hv_cpu_startup:
        SET_GL(0)
-       wrpr            %g0, 15, %pil
+       wrpr            %g0, PIL_NORMAL_MAX, %pil
        wrpr            %g0, 0, %canrestore
        wrpr            %g0, 0, %otherwin
        wrpr            %g0, 6, %cansave
index c6d06362728c3cf8694bcc49529aefdac8db24fc..b5225c81556c691e4ac43404cd42d929397a2e68 100644 (file)
@@ -1146,8 +1146,8 @@ void smp_release(void)
        }
 }
 
-/* Imprisoned penguins run with %pil == 15, but PSTATE_IE set, so they
- * can service tlb flush xcalls...
+/* Imprisoned penguins run with %pil == PIL_NORMAL_MAX, but PSTATE_IE
+ * set, so they can service tlb flush xcalls...
  */
 extern void prom_world(int);
 
index ef902c6f8e3cefa641f0267d3c388e31279a4553..c357e40ffd01526ca38a824c12ac077cdba135c6 100644 (file)
@@ -80,7 +80,7 @@ __spitfire_cee_trap_continue:
        cmp             %g2, 1
        rdpr            %pil, %g2
        bleu,pt         %xcc, 1f
-        wrpr           %g0, 15, %pil
+        wrpr           %g0, PIL_NORMAL_MAX, %pil
 
        ba,pt           %xcc, etraptl1
         rd             %pc, %g7
index e2f8e1b4882a7f8cbc0c9a77c4eef33f473b7cac..559bc5e9c199232d092ec425d705a016b639db9a 100644 (file)
@@ -186,7 +186,7 @@ sun4v_res_mondo:
         * when it's done.
         */
        rdpr    %pil, %g2
-       wrpr    %g0, 15, %pil
+       wrpr    %g0, PIL_NORMAL_MAX, %pil
        mov     %g1, %g4
        ba,pt   %xcc, etrap_irq
         rd     %pc, %g7
@@ -216,7 +216,7 @@ sun4v_res_mondo_queue_full:
        membar  #Sync
 
        rdpr    %pil, %g2
-       wrpr    %g0, 15, %pil
+       wrpr    %g0, PIL_NORMAL_MAX, %pil
        ba,pt   %xcc, etrap_irq
         rd     %pc, %g7
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -297,7 +297,7 @@ sun4v_nonres_mondo:
         * when it's done.
         */
        rdpr    %pil, %g2
-       wrpr    %g0, 15, %pil
+       wrpr    %g0, PIL_NORMAL_MAX, %pil
        mov     %g1, %g4
        ba,pt   %xcc, etrap_irq
         rd     %pc, %g7
@@ -327,7 +327,7 @@ sun4v_nonres_mondo_queue_full:
        membar  #Sync
 
        rdpr    %pil, %g2
-       wrpr    %g0, 15, %pil
+       wrpr    %g0, PIL_NORMAL_MAX, %pil
        ba,pt   %xcc, etrap_irq
         rd     %pc, %g7
 #ifdef CONFIG_TRACE_IRQFLAGS
index 04994fc8700d62a172c399b5beb1f9b61985a04f..4638af2f55a0bb5d50c9b0b8425001d7e0845279 100644 (file)
@@ -1832,7 +1832,7 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent,
        }
 }
 
-/* We run with %pil set to 15 and PSTATE_IE enabled in %pstate.
+/* We run with %pil set to PIL_NORMAL_MAX and PSTATE_IE enabled in %pstate.
  * Log the event and clear the first word of the entry.
  */
 void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)
@@ -1880,7 +1880,7 @@ void sun4v_resum_overflow(struct pt_regs *regs)
        atomic_inc(&sun4v_resum_oflow_cnt);
 }
 
-/* We run with %pil set to 15 and PSTATE_IE enabled in %pstate.
+/* We run with %pil set to PIL_NORMAL_MAX and PSTATE_IE enabled in %pstate.
  * Log the event, clear the first word of the entry, and die.
  */
 void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset)
index 2a31ffa4c28d9385a8eb211dd174048c9cfee368..ea925503b42e59fa051d591ebf752eb708243c7d 100644 (file)
@@ -66,7 +66,7 @@ tl0_irq6:     BTRAP(0x46)
 tl0_irq7:      BTRAP(0x47) BTRAP(0x48) BTRAP(0x49)
 tl0_irq10:     BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d)
 tl0_irq14:     TRAP_IRQ(timer_interrupt, 14)
-tl0_irq15:     TRAP_IRQ(perfctr_irq, 15)
+tl0_irq15:     TRAP_NMI_IRQ(perfctr_irq, 15)
 tl0_resv050:   BTRAP(0x50) BTRAP(0x51) BTRAP(0x52) BTRAP(0x53) BTRAP(0x54) BTRAP(0x55)
 tl0_resv056:   BTRAP(0x56) BTRAP(0x57) BTRAP(0x58) BTRAP(0x59) BTRAP(0x5a) BTRAP(0x5b)
 tl0_resv05c:   BTRAP(0x5c) BTRAP(0x5d) BTRAP(0x5e) BTRAP(0x5f)