Skip to content

Commit 23d2626

Browse files
sandip4nIngo Molnar
authored andcommitted
perf/x86/amd/core: Fix overflow reset on hotplug
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
1 parent ce9ecca commit 23d2626

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

arch/x86/events/amd/core.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,12 @@ static void amd_pmu_cpu_reset(int cpu)
534534
/* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */
535535
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0);
536536

537-
/* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */
538-
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask);
537+
/*
538+
* Clear freeze and overflow bits i.e. PerfCntrGLobalStatus.LbrFreeze
539+
* and PerfCntrGLobalStatus.PerfCntrOvfl
540+
*/
541+
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR,
542+
GLOBAL_STATUS_LBRS_FROZEN | amd_pmu_global_cntr_mask);
539543
}
540544

541545
static int amd_pmu_cpu_prepare(int cpu)
@@ -570,6 +574,7 @@ static void amd_pmu_cpu_starting(int cpu)
570574
int i, nb_id;
571575

572576
cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
577+
amd_pmu_cpu_reset(cpu);
573578

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

592597
cpuc->amd_nb->nb_id = nb_id;
593598
cpuc->amd_nb->refcnt++;
594-
595-
amd_pmu_cpu_reset(cpu);
596599
}
597600

598601
static void amd_pmu_cpu_dead(int cpu)
@@ -601,6 +604,7 @@ static void amd_pmu_cpu_dead(int cpu)
601604

602605
kfree(cpuhw->lbr_sel);
603606
cpuhw->lbr_sel = NULL;
607+
amd_pmu_cpu_reset(cpu);
604608

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

614618
cpuhw->amd_nb = NULL;
615619
}
616-
617-
amd_pmu_cpu_reset(cpu);
618620
}
619621

620622
static inline void amd_pmu_set_global_ctl(u64 ctl)

0 commit comments

Comments
 (0)