]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
powerpc/64: Don't trace code that runs with the soft irq mask unreconciled
authorNicholas Piggin <npiggin@gmail.com>
Thu, 2 May 2019 05:21:07 +0000 (15:21 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 2 May 2019 15:58:11 +0000 (01:58 +1000)
"Reconciling" in terms of interrupt handling, is to bring the soft irq
mask state in to synch with the hardware, after an interrupt causes
MSR[EE] to be cleared (while the soft mask may be enabled, and hard
irqs not marked disabled).

General kernel code should not be called while unreconciled, because
local_irq_disable, etc. manipulations can cause surprising irq traces,
and it's fragile because the soft irq code does not really expect to
be called in this situation.

When exiting from an interrupt, MSR[EE] is cleared to prevent races,
but soft irq state is enabled for the returned-to context, so this is
now an unreconciled state. restore_math is called in this state, and
that can be ftraced, and the ftrace subsystem disables local irqs.

Mark restore_math and its callees as notrace. Restore a sanity check
in the soft irq code that had to be disabled for this case, by commit
4da1f79227ad4 ("powerpc/64: Disable irq restore warning for now").

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/fpu.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/vector.S

index 529dcc21c3f91bd2646f9519d95edb7664b9e7f8..cecd57e1d0468dd84995d19e96f61f63f544bccc 100644 (file)
@@ -63,6 +63,7 @@ _GLOBAL(load_fp_state)
        REST_32FPVSRS(0, R4, R3)
        blr
 EXPORT_SYMBOL(load_fp_state)
+_ASM_NOKPROBE_SYMBOL(load_fp_state); /* used by restore_math */
 
 /*
  * Store FP state into memory, including FPSCR
index 6672fec75e2a7573dff50471112e20792abcbc51..ada901af4950c874e08f368275d7fbc1facf7e61 100644 (file)
@@ -258,16 +258,9 @@ notrace void arch_local_irq_restore(unsigned long mask)
         */
        irq_happened = get_irq_happened();
        if (!irq_happened) {
-               /*
-                * FIXME. Here we'd like to be able to do:
-                *
-                * #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
-                *   WARN_ON(!(mfmsr() & MSR_EE));
-                * #endif
-                *
-                * But currently it hits in a few paths, we should fix those and
-                * enable the warning.
-                */
+#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
+               WARN_ON(!(mfmsr() & MSR_EE));
+#endif
                return;
        }
 
index 0c201735707315f1945845ffd3a5266dd39aacdb..87da40129927ce9b145d110ba384be7d29545461 100644 (file)
@@ -134,7 +134,8 @@ static int __init enable_strict_msr_control(char *str)
 }
 early_param("ppc_strict_facility_enable", enable_strict_msr_control);
 
-unsigned long msr_check_and_set(unsigned long bits)
+/* notrace because it's called by restore_math */
+unsigned long notrace msr_check_and_set(unsigned long bits)
 {
        unsigned long oldmsr = mfmsr();
        unsigned long newmsr;
@@ -153,7 +154,8 @@ unsigned long msr_check_and_set(unsigned long bits)
 }
 EXPORT_SYMBOL_GPL(msr_check_and_set);
 
-void __msr_check_and_clear(unsigned long bits)
+/* notrace because it's called by restore_math */
+void notrace __msr_check_and_clear(unsigned long bits)
 {
        unsigned long oldmsr = mfmsr();
        unsigned long newmsr;
@@ -526,7 +528,17 @@ void giveup_all(struct task_struct *tsk)
 }
 EXPORT_SYMBOL(giveup_all);
 
-void restore_math(struct pt_regs *regs)
+/*
+ * The exception exit path calls restore_math() with interrupts hard disabled
+ * but the soft irq state not "reconciled". ftrace code that calls
+ * local_irq_save/restore causes warnings.
+ *
+ * Rather than complicate the exit path, just don't trace restore_math. This
+ * could be done by having ftrace entry code check for this un-reconciled
+ * condition where MSR[EE]=0 and PACA_IRQ_HARD_DIS is not set, and
+ * temporarily fix it up for the duration of the ftrace call.
+ */
+void notrace restore_math(struct pt_regs *regs)
 {
        unsigned long msr;
 
index 21165da0052d0f86ea7604715f668015563e0af2..8eb867dbad5fd92c95feea2345f9ea0d5d7694bf 100644 (file)
@@ -21,6 +21,7 @@ _GLOBAL(load_vr_state)
        REST_32VRS(0,r4,r3)
        blr
 EXPORT_SYMBOL(load_vr_state)
+_ASM_NOKPROBE_SYMBOL(load_vr_state); /* used by restore_math */
 
 /*
  * Store VMX state into memory, including VSCR.