Date: Tue, 09 Jun 2026 19:46:34 +0000 From: Mitchell Horne <mhorne@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Ali Mashtizadeh <ali@mashtizadeh.com> Subject: git: dded0ab415cc - main - hwpmc: Disable AMD PMCs if in an unsupported VM Message-ID: <6a286d9a.1978c.49e1669d@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=dded0ab415cc09eed506968366e383d406834823 commit dded0ab415cc09eed506968366e383d406834823 Author: Ali Mashtizadeh <ali@mashtizadeh.com> AuthorDate: 2026-06-05 23:48:53 +0000 Commit: Mitchell Horne <mhorne@FreeBSD.org> CommitDate: 2026-06-09 19:46:31 +0000 hwpmc: Disable AMD PMCs if in an unsupported VM AMD does not have a CPUID bit to indicate the lack of K8 PMCs. If all other PMC features are not present we should test an event selector to see if it stores and returns a value. If the VM is implemented correctly, this should result in a #GP on the initial wrmsr_safe. Bhyve and a few other VMs ignore writes, so I got one step further and test that it retains the OS and 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 <jfc@mit.edu> 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 usehome | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a286d9a.1978c.49e1669d>
