Skip to content

Commit

Permalink
perf/x86/amd/core: Fix overflow reset on hotplug
Browse files Browse the repository at this point in the history
Kernels older than v5.19 do not support PerfMonV2 and the PMI handler
does not clear the overflow bits of the PerfCntrGlobalStatus register.
Because of this, loading a recent kernel using kexec from an older
kernel can result in inconsistent register states on Zen 4 systems.

The PMI handler of the new kernel gets confused and shows a warning when
an overflow occurs because some of the overflow bits are set even if the
corresponding counters are inactive. These are remnants from overflows
that were handled by the older kernel.

During CPU hotplug, the PerfCntrGlobalCtl and PerfCntrGlobalStatus
registers should always be cleared for PerfMonV2-capable processors.
However, a condition used for NB event constaints applicable only to
older processors currently prevents this from happening. Move the reset
sequence to an appropriate place and also clear the LBR Freeze bit.

Fixes: 21d59e3 ("perf/x86/amd/core: Detect PerfMonV2 support")
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/882a87511af40792ba69bb0e9026f19a2e71e8a3.1694696888.git.sandipan.das@amd.com
  • Loading branch information
Sandipan Das authored and Ingo Molnar committed Sep 22, 2023
1 parent ce9ecca commit 23d2626
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions arch/x86/events/amd/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,12 @@ static void amd_pmu_cpu_reset(int cpu)
/* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0);

/* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask);
/*
* Clear freeze and overflow bits i.e. PerfCntrGLobalStatus.LbrFreeze
* and PerfCntrGLobalStatus.PerfCntrOvfl
*/
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR,
GLOBAL_STATUS_LBRS_FROZEN | amd_pmu_global_cntr_mask);
}

static int amd_pmu_cpu_prepare(int cpu)
Expand Down Expand Up @@ -570,6 +574,7 @@ static void amd_pmu_cpu_starting(int cpu)
int i, nb_id;

cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
amd_pmu_cpu_reset(cpu);

if (!x86_pmu.amd_nb_constraints)
return;
Expand All @@ -591,8 +596,6 @@ static void amd_pmu_cpu_starting(int cpu)

cpuc->amd_nb->nb_id = nb_id;
cpuc->amd_nb->refcnt++;

amd_pmu_cpu_reset(cpu);
}

static void amd_pmu_cpu_dead(int cpu)
Expand All @@ -601,6 +604,7 @@ static void amd_pmu_cpu_dead(int cpu)

kfree(cpuhw->lbr_sel);
cpuhw->lbr_sel = NULL;
amd_pmu_cpu_reset(cpu);

if (!x86_pmu.amd_nb_constraints)
return;
Expand All @@ -613,8 +617,6 @@ static void amd_pmu_cpu_dead(int cpu)

cpuhw->amd_nb = NULL;
}

amd_pmu_cpu_reset(cpu);
}

static inline void amd_pmu_set_global_ctl(u64 ctl)
Expand Down

0 comments on commit 23d2626

Please sign in to comment.