From 3c1f73b18d318cc7be8c1b9c19933c2eaa1f1771 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sun, 30 Oct 2016 09:38:10 +0000 Subject: [PATCH] hwpmc: fix a race between amd_stop_pmc and amd_intr It is possible that wrmsr in amd_stop_pmc() causes an overflow in a counter that it disables. In that case a non-maskable interrupt is generated. The interrupt handler code was written in such a way that it would re-enable the counter. That would lead to an unexpected interrupt later on. This problem was easy to reproduce with $ pmcstat -T -P instructions -t $pid if the target process is sufficiently busy and there are context switches from time to time. There would be a lot of interrupts to "race" with amd_stop_pmc() called during the context switches. The problem affected only AMD processors. While there, trace whether amd_intr() claimed an interrupt. Reviewed by: jhb MFC after: 2 weeks --- sys/dev/hwpmc/hwpmc_amd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index 14d708aee949..7221071de0f8 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -689,12 +689,13 @@ amd_intr(int cpu, struct trapframe *tf) error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, TRAPF_USERMODE(tf)); if (error == 0) - wrmsr(evsel, config | AMD_PMC_ENABLE); + wrmsr(evsel, config); } atomic_add_int(retval ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); + PMCDBG1(MDP,INT,2, "retval=%d", retval); return (retval); }