USR bits. Tested on Zen 5 native and a Zen 5 Bhyve virtual machine. This code should not run on any recent hardware, except in a VM, as it checks that the core counter extension is missing. PR: 268943 Reported by: Sandipan Das, John F. Carr Reviewed by: mhorne, imp Sponsored by: Netflix MFC after: 1 week Pull Request: https://github.com/freebsd/freebsd-src/pull/2272/changes --- sys/dev/hwpmc/hwpmc_amd.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index 299021494716..e76bdef118d5 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -869,12 +869,14 @@ amd_pcpu_fini(struct pmc_mdep *md, int cpu) struct pmc_mdep * pmc_amd_initialize(void) { + struct amd_descr *d; struct pmc_classdep *pcd; struct pmc_mdep *pmc_mdep; + uint64_t reg; enum pmc_cputype cputype; - int error, i, ncpus, nclasses; + int ncpus, nclasses, i; int family, model, stepping; - struct amd_descr *d; + int error; /* * The presence of hardware performance counters on the AMD @@ -905,6 +907,37 @@ pmc_amd_initialize(void) return (NULL); } + /* + * Unforunately, there is no way to communicate that the original four + * core counters are disabled through CPUIDs alone. We attempt to + * write and read back the MSR to validate that it is working. + * + * Referenced the BIOS and Kernel Developer Guide for AMD Athlon 64 and + * AMD Opteron Processors 26094 Rev. 3.24 January, 2005 to ensure these + * fields are valid. + */ + if ((amd_feature2 & AMDID2_PCXC) == 0) { + error = wrmsr_safe(AMD_PMC_EVSEL_0, AMD_PMC_OS | AMD_PMC_USR); + if (error != 0) { + printf("hwpmc: AMD evsel 0 wrmsr failed!\n"); + return (NULL); + } + + error = rdmsr_safe(AMD_PMC_EVSEL_0, ®); + if (error != 0) { + printf("hwpmc: AMD evsel 0 rdmsr failed!\n"); + return (NULL); + } + + if (reg == 0) { + printf("hwpmc: AMD evsel returned invalid value! " + "You may be in a VM without PMC support.\n"); + return (NULL); + } + + wrmsr(AMD_PMC_EVSEL_0, 0); + } + /* * From PPR for AMD Family 1Ah, a new cpuid leaf specifies the maximum * number of PMCs of each type. If we do not have that leaf, we use