Skip to content

Commit c698169

Browse files
Kan Lianggregkh
authored andcommitted
perf/x86/intel: Properly save/restore the PMU state in the NMI handler
[ Upstream commit 82d71ed ] The PMU is disabled in intel_pmu_handle_irq(), but cpuc->enabled is not updated accordingly. This is fine in current usage because no-one checks it - but fix it for future code: for example, the drain_pebs() will be modified to fix an auto-reload bug. Properly save/restore the old PMU state. Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Cc: [email protected] Cc: kernel test robot <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5556bf8 commit c698169

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

arch/x86/events/intel/core.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2066,16 +2066,23 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
20662066
int bit, loops;
20672067
u64 status;
20682068
int handled;
2069+
int pmu_enabled;
20692070

20702071
cpuc = this_cpu_ptr(&cpu_hw_events);
20712072

2073+
/*
2074+
* Save the PMU state.
2075+
* It needs to be restored when leaving the handler.
2076+
*/
2077+
pmu_enabled = cpuc->enabled;
20722078
/*
20732079
* No known reason to not always do late ACK,
20742080
* but just in case do it opt-in.
20752081
*/
20762082
if (!x86_pmu.late_ack)
20772083
apic_write(APIC_LVTPC, APIC_DM_NMI);
20782084
intel_bts_disable_local();
2085+
cpuc->enabled = 0;
20792086
__intel_pmu_disable_all();
20802087
handled = intel_pmu_drain_bts_buffer();
20812088
handled += intel_bts_interrupt();
@@ -2173,7 +2180,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
21732180

21742181
done:
21752182
/* Only restore PMU state when it's active. See x86_pmu_disable(). */
2176-
if (cpuc->enabled)
2183+
cpuc->enabled = pmu_enabled;
2184+
if (pmu_enabled)
21772185
__intel_pmu_enable_all(0, true);
21782186
intel_bts_enable_local();
21792187

0 commit comments

Comments
 (0)