Commit 017f2ee2 authored by Kan Liang's avatar Kan Liang Committed by Greg Kroah-Hartman

perf/x86/intel: Properly save/restore the PMU state in the NMI handler

[ Upstream commit 82d71ed0 ]

The PMU is disabled in intel_pmu_handle_irq(), but cpuc->enabled is not updated

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: default avatarKan Liang <>
Signed-off-by: default avatarPeter Zijlstra (Intel) <>
Cc: Alexander Shishkin <>
Cc: Arnaldo Carvalho de Melo <>
Cc: Jiri Olsa <>
Cc: Linus Torvalds <>
Cc: Peter Zijlstra <>
Cc: Stephane Eranian <>
Cc: Thomas Gleixner <>
Cc: Vince Weaver <>
Cc: kernel test robot <>
Link: default avatarIngo Molnar <>
Signed-off-by: default avatarSasha Levin <>
Signed-off-by: default avatarGreg Kroah-Hartman <>
parent 8f8ebc0b
......@@ -2201,9 +2201,15 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
int bit, loops;
u64 status;
int handled;
int pmu_enabled;
cpuc = this_cpu_ptr(&cpu_hw_events);
* Save the PMU state.
* It needs to be restored when leaving the handler.
pmu_enabled = cpuc->enabled;
* No known reason to not always do late ACK,
* but just in case do it opt-in.
......@@ -2211,6 +2217,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
if (!x86_pmu.late_ack)
apic_write(APIC_LVTPC, APIC_DM_NMI);
cpuc->enabled = 0;
handled = intel_pmu_drain_bts_buffer();
handled += intel_bts_interrupt();
......@@ -2320,7 +2327,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
/* Only restore PMU state when it's active. See x86_pmu_disable(). */
if (cpuc->enabled)
cpuc->enabled = pmu_enabled;
if (pmu_enabled)
__intel_pmu_enable_all(0, true);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment