Skip to content

Commit 11a1459

Browse files
Kan Lianggregkh
Kan Liang
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 1a596a9 commit 11a1459

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

arch/x86/events/intel/core.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -2201,16 +2201,23 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
22012201
int bit, loops;
22022202
u64 status;
22032203
int handled;
2204+
int pmu_enabled;
22042205

22052206
cpuc = this_cpu_ptr(&cpu_hw_events);
22062207

2208+
/*
2209+
* Save the PMU state.
2210+
* It needs to be restored when leaving the handler.
2211+
*/
2212+
pmu_enabled = cpuc->enabled;
22072213
/*
22082214
* No known reason to not always do late ACK,
22092215
* but just in case do it opt-in.
22102216
*/
22112217
if (!x86_pmu.late_ack)
22122218
apic_write(APIC_LVTPC, APIC_DM_NMI);
22132219
intel_bts_disable_local();
2220+
cpuc->enabled = 0;
22142221
__intel_pmu_disable_all();
22152222
handled = intel_pmu_drain_bts_buffer();
22162223
handled += intel_bts_interrupt();
@@ -2320,7 +2327,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
23202327

23212328
done:
23222329
/* Only restore PMU state when it's active. See x86_pmu_disable(). */
2323-
if (cpuc->enabled)
2330+
cpuc->enabled = pmu_enabled;
2331+
if (pmu_enabled)
23242332
__intel_pmu_enable_all(0, true);
23252333
intel_bts_enable_local();
23262334

0 commit comments

Comments
 (0)