diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2021-01-30 14:08:29 +0100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2021-02-08 14:02:10 +0100 |
commit | 156b5371a9c2482a9ad23ec82d1a4f89a3ab430d (patch) | |
tree | 2bd0839a1b8d0c5d2d8b9cb112f4fe6f72c3d3a4 /arch/powerpc/kernel/traps.c | |
parent | powerpc/traps: add NOKPROBE_SYMBOL for sreset and mce (diff) | |
download | linux-156b5371a9c2482a9ad23ec82d1a4f89a3ab430d.tar.xz linux-156b5371a9c2482a9ad23ec82d1a4f89a3ab430d.zip |
powerpc/perf: move perf irq/nmi handling details into traps.c
This is required in order to allow more significant differences between
NMI type interrupt handlers and regular asynchronous handlers.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210130130852.2952424-20-npiggin@gmail.com
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 4349b25807cf..6da3a3642dfb 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1892,11 +1892,40 @@ void vsx_unavailable_tm(struct pt_regs *regs) } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -void performance_monitor_exception(struct pt_regs *regs) +static void performance_monitor_exception_nmi(struct pt_regs *regs) +{ + nmi_enter(); + + __this_cpu_inc(irq_stat.pmu_irqs); + + perf_irq(regs); + + nmi_exit(); +} + +static void performance_monitor_exception_async(struct pt_regs *regs) { + irq_enter(); + __this_cpu_inc(irq_stat.pmu_irqs); perf_irq(regs); + + irq_exit(); +} + +void performance_monitor_exception(struct pt_regs *regs) +{ + /* + * On 64-bit, if perf interrupts hit in a local_irq_disable + * (soft-masked) region, we consider them as NMIs. This is required to + * prevent hash faults on user addresses when reading callchains (and + * looks better from an irq tracing perspective). + */ + if (IS_ENABLED(CONFIG_PPC64) && unlikely(arch_irq_disabled_regs(regs))) + performance_monitor_exception_nmi(regs); + else + performance_monitor_exception_async(regs); } #ifdef CONFIG_PPC_ADV_DEBUG_REGS |