summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/interrupt.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2022-10-07 00:04:11 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2022-10-18 22:46:19 +1100
commitdc398a084d459f065658855454e09f2778f8c5cc (patch)
treedba45be1f6d86775998339cbebcdc038f931a203 /arch/powerpc/kernel/interrupt.c
parenta073672eb09670540e95a2a4aa1c46f5da74159f (diff)
downloadlinux-dc398a084d459f065658855454e09f2778f8c5cc.tar.gz
linux-dc398a084d459f065658855454e09f2778f8c5cc.tar.bz2
linux-dc398a084d459f065658855454e09f2778f8c5cc.zip
powerpc/64s/interrupt: Perf NMI should not take normal exit path
NMI interrupts should exit with EXCEPTION_RESTORE_REGS not with interrupt_return_srr, which is what the perf NMI handler currently does. This breaks if a PMI hits after interrupt_exit_user_prepare_main() has switched the context tracking to user mode, then the CT_WARN_ON() in interrupt_exit_kernel_prepare() fires because it returns to kernel with context set to user. This could possibly be solved by soft-disabling PMIs in the exit path, but that reduces our ability to profile that code. The warning could be removed, but it's potentially useful. All other NMIs and soft-NMIs return using EXCEPTION_RESTORE_REGS, so this makes perf interrupts consistent with that and seems like the best fix. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> [mpe: Squash in fixups from Nick] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20221006140413.126443-3-npiggin@gmail.com
Diffstat (limited to 'arch/powerpc/kernel/interrupt.c')
-rw-r--r--arch/powerpc/kernel/interrupt.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 7bc93367de68..fc6631a80527 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -377,13 +377,15 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
* CT_WARN_ON comes here via program_check_exception, so avoid
* recursion.
*
- * Skip the assertion on PMIs to work around a problem caused by NMI
- * PMIs incorrectly taking this interrupt return path, it's possible
- * for this to hit after interrupt exit to user switches context to
- * user. See also the comment in the performance monitor handler in
- * exceptions-64e/s.S
+ * Skip the assertion on PMIs on 64e to work around a problem caused
+ * by NMI PMIs incorrectly taking this interrupt return path, it's
+ * possible for this to hit after interrupt exit to user switches
+ * context to user. See also the comment in the performance monitor
+ * handler in exceptions-64e.S
*/
- if (TRAP(regs) != INTERRUPT_PROGRAM && TRAP(regs) != INTERRUPT_PERFMON)
+ if (!IS_ENABLED(CONFIG_PPC_BOOK3E_64) &&
+ TRAP(regs) != INTERRUPT_PROGRAM &&
+ TRAP(regs) != INTERRUPT_PERFMON)
CT_WARN_ON(ct_state() == CONTEXT_USER);
kuap = kuap_get_and_assert_locked();