The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=0698ce429f78f548f7eb3e54476fb312109ddd8b
commit 0698ce429f78f548f7eb3e54476fb312109ddd8b Author: Konstantin Belousov <k...@freebsd.org> AuthorDate: 2024-12-17 21:09:33 +0000 Commit: Konstantin Belousov <k...@freebsd.org> CommitDate: 2025-03-05 12:27:58 +0000 bhyve: fix CPUID L3 Cache Size reporting for AMD/SVM Adjust leaf 0x8000_001D %ecx 3 on AMD (L3 cache params). - Report cache as 1-way associative. Glibc does not believe that there are fully associative L3 caches, ignoring the leaf and falling back to legacy way of reading cache params. - Do not report 4095 logical CPUs per L3 cache, report the true total number of emulated CPUs. The insanely large value tricked some version of glibc to overflow 32bit calculation of the L3 cache size, as reported in the PR. Also, for leaf 0x8000_0008, do not clip ApicIdSize to zero if less than 4. This effectively falls back to legacy. PR: 279901 With the help from: Florian Weimer <fwei...@redhat.com> Reviewed by: kevans, meta, mp Tested by: meta, mp Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D48187 --- sys/amd64/vmm/x86.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c index a833b61786e7..366f1da9f850 100644 --- a/sys/amd64/vmm/x86.c +++ b/sys/amd64/vmm/x86.c @@ -150,8 +150,6 @@ x86_emulate_cpuid(struct vcpu *vcpu, uint64_t *rax, uint64_t *rbx, * pkg_id_shift and other OSes may rely on it. */ width = MIN(0xF, log2(threads * cores)); - if (width < 0x4) - width = 0; logical_cpus = MIN(0xFF, threads * cores - 1); regs[2] = (width << AMDID_COREID_SIZE_SHIFT) | logical_cpus; } @@ -256,7 +254,7 @@ x86_emulate_cpuid(struct vcpu *vcpu, uint64_t *rax, uint64_t *rbx, func = 3; /* unified cache */ break; default: - logical_cpus = 0; + logical_cpus = sockets * threads * cores; level = 0; func = 0; break; @@ -266,7 +264,14 @@ x86_emulate_cpuid(struct vcpu *vcpu, uint64_t *rax, uint64_t *rbx, regs[0] = (logical_cpus << 14) | (1 << 8) | (level << 5) | func; regs[1] = (func > 0) ? (CACHE_LINE_SIZE - 1) : 0; + + /* + * ecx: Number of cache ways for non-fully + * associative cache, minus 1. Reported value + * of zero means there is one way. + */ regs[2] = 0; + regs[3] = 0; break;