Skip to content

Commit a4016a7

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
perf_counter: x86: Robustify interrupt handling
Two consecutive NMIs could daze and confuse the machine when the first would handle the overflow of both counters. [ Impact: fix false-positive syslog messages under multi-session profiling ] Signed-off-by: Peter Zijlstra <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Corey Ashford <[email protected]> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <[email protected]>
1 parent 9e35ad3 commit a4016a7

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

arch/x86/kernel/cpu/perf_counter.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,10 @@ static int amd_pmu_handle_irq(struct pt_regs *regs, int nmi)
783783

784784
counter = cpuc->counters[idx];
785785
hwc = &counter->hw;
786+
787+
if (counter->hw_event.nmi != nmi)
788+
goto next;
789+
786790
val = x86_perf_counter_update(counter, hwc, idx);
787791
if (val & (1ULL << (x86_pmu.counter_bits - 1)))
788792
goto next;
@@ -869,7 +873,6 @@ perf_counter_nmi_handler(struct notifier_block *self,
869873
{
870874
struct die_args *args = __args;
871875
struct pt_regs *regs;
872-
int ret;
873876

874877
if (!atomic_read(&active_counters))
875878
return NOTIFY_DONE;
@@ -886,9 +889,16 @@ perf_counter_nmi_handler(struct notifier_block *self,
886889
regs = args->regs;
887890

888891
apic_write(APIC_LVTPC, APIC_DM_NMI);
889-
ret = x86_pmu.handle_irq(regs, 1);
892+
/*
893+
* Can't rely on the handled return value to say it was our NMI, two
894+
* counters could trigger 'simultaneously' raising two back-to-back NMIs.
895+
*
896+
* If the first NMI handles both, the latter will be empty and daze
897+
* the CPU.
898+
*/
899+
x86_pmu.handle_irq(regs, 1);
890900

891-
return ret ? NOTIFY_STOP : NOTIFY_OK;
901+
return NOTIFY_STOP;
892902
}
893903

894904
static __read_mostly struct notifier_block perf_counter_nmi_notifier = {

0 commit comments

Comments
 (0)