On a Beelink ME Mini host with the Intel N150 and running a fresh install of FreeBSD 15.1-RELEASE, A bhyve vm (manged by vm-bhyve) running FreeBSD 15.1-RELEASE reports 2 cores with 2 threads per core vs the actual topology of 4 cores with 1 thread per core. In the vm-bhyve config file, the processor topology is explicitly set to cpu_sockets=1, cpu_cores=4, cpu_threads=1. This is the CPU reporting output from sysctl on the vm: CPU: Intel(R) N150 (800.00-MHz K8-class CPU) Origin="GenuineIntel" Id=0xb06e0 Family=0x6 Model=0xbe Stepping=0 Features=0x9f83fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,SS,HTT,PBE> Features2=0xfeda7a17<SSE3,PCLMULQDQ,DTES64,DS_CPL,SSSE3,SDBG,FMA,CX16,xTPR,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND,HV> AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM> AMD Features2=0x121<LAHF,ABM,Prefetch> Structured Extended Features=0x201407a9<FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,SMAP,SHA> Structured Extended Features2=0x400600<VAES,VPCLMULQDQ,RDPID> Structured Extended Features3=0x400<MD_CLEAR> XSAVE Features=0x1<XSAVEOPT> TSC: P-state invariant Hypervisor: Origin = "bhyve bhyve " real memory = 2147483648 (2048 MB) avail memory = 2048409600 (1953 MB) Event timer "LAPIC" quality 600 ACPI APIC Table: <BHYVE BVAPIC > WARNING: L1 data cache covers fewer APIC IDs than a core (0 < 1) WARNING: L2 data cache covers fewer APIC IDs than a core (0 < 1) FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs FreeBSD/SMP: 1 package(s) x 2 core(s) x 2 hardware threads The host system seems to recognize the proper topology. Here is sysctl output from the host system CPU: Intel(R) N150 (800.00-MHz K8-class CPU) Origin="GenuineIntel" Id=0xb06e0 Family=0x6 Model=0xbe Stepping=0 Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE> Features2=0x7ffafbff<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,SMX,EST,TM2,SSSE3,SDBG,FMA,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,TSCDLT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND> AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM> AMD Features2=0x121<LAHF,ABM,Prefetch> Structured Extended Features=0x239ca7eb<FSGSBASE,TSCADJ,BMI1,AVX2,FDPEXC,SMEP,BMI2,ERMS,INVPCID,NFPUSG,PQE,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,PROCTRACE,SHA> Structured Extended Features2=0x98c007bc<UMIP,PKU,OSPKE,WAITPKG,GFNI,VAES,VPCLMULQDQ,RDPID,MOVDIRI,MOVDIR64B> Structured Extended Features3=0xfc184410<FSRM,MD_CLEAR,IBT,IBPB,STIBP,L1DFL,ARCH_CAP,CORE_CAP,SSBD> Structured Extended Features4=0x810 XSAVE Features=0xf<XSAVEOPT,XSAVEC,XINUSE,XSAVES> IA32_ARCH_CAPS=0x1580fd6b<RDCL_NO,IBRS_ALL,SKIP_L1DFL_VME,MDS_NO,TAA_NO> VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID,VID,PostIntr TSC: P-state invariant, performance statistics real memory = 17179869184 (16384 MB) avail memory = 16401031168 (15641 MB) Event timer "LAPIC" quality 600 ACPI APIC Table: <ALASKA A M I > WARNING: L3 data cache covers more APIC IDs than a package (7 > 3) FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs FreeBSD/SMP: 1 package(s) x 4 core(s) Note that both the vm and host appear to have warnings regarding the L3 data cache and the APIC IDs, though they are different warnings. Perhaps that has something to do with this issue. Also, PR297032 reports the same host warnings for an N150 processor system.
A FreeBSD guest prefers CPUID leaf 1Fh over 0Bh since 6badb512a94d whenever the host reports a maximum basic leaf of 1Fh or higher, which the N150 does. bhyve does not emulate leaf 1Fh, so the host values are passed through and the guest ends up enumerating the host topology. With an SMT shift of 1 that results in exactly the 2 cores x 2 threads you are seeing. Proposed fix: https://reviews.freebsd.org/D58885 I have no affected hardware available, so a test on your N150 would be very welcome.
would this also affect the Xeon E-2468? i have such a system where machdep.hyperthreading_allowed=0, and with bhyve -c8, VMs still detect 2 hardware threads. i've tried various combinations of explicit CPU-topology configuration in bhyve and couldn't find a way to fix it. CPU: Intel(R) Xeon(R) E E-2468 (2600.00-MHz K8-class CPU) Origin="GenuineIntel" Id=0xb0671 Family=0x6 Model=0xb7 Stepping=1 Features=0x9f83fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,SS,HTT,PBE> Features2=0xfeda7a17<SSE3,PCLMULQDQ,DTES64,DS_CPL,SSSE3,SDBG,FMA,CX16,xTPR,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND,HV> AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM> AMD Features2=0x121<LAHF,ABM,Prefetch> Structured Extended Features=0x201407a9<FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,SMAP,SHA> Structured Extended Features2=0x400600<VAES,VPCLMULQDQ,RDPID> Structured Extended Features3=0x400<MD_CLEAR> XSAVE Features=0x1<XSAVEOPT> TSC: P-state invariant Hypervisor: Origin = "bhyve bhyve " real memory = 17179869184 (16384 MB) avail memory = 16639295488 (15868 MB) Event timer "LAPIC" quality 600 ACPI APIC Table: <BHYVE BVAPIC > WARNING: L1 data cache covers fewer APIC IDs than a core (0 < 1) WARNING: L2 data cache covers fewer APIC IDs than a core (0 < 1) WARNING: L3 data cache covers fewer APIC IDs than a core (0 < 1) FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs FreeBSD/SMP: 1 package(s) x 4 cache groups x 1 core(s) x 2 hardware threads (i previously posted about this on the list: https://lists.freebsd.org/archives/freebsd-virtualization/2025-July/003018.html)
(In reply to Lexi Winter from comment #2) Yes, the E-2468 is affected the same way. It reports a maximum basic leaf above 1Fh, so the guest takes the 1Fh path and reads the host's values, where the SMT shift is 1 regardless of machdep.hyperthreading_allowed, which only affects the host scheduler and not CPUID. With -c8 the guest derives 4 cores x 2 threads instead of 8 x 1, and explicit topology settings have no effect because they end up in leaf 0Bh, which the guest no longer reads. D58885 adds the missing emulation of leaf 1Fh. A test on that machine would be very welcome.
i've tested the patch (using 15.0 on the host) and it seems to fix the problem: Hypervisor: Origin = "bhyve bhyve " real memory = 17179869184 (16384 MB) avail memory = 16639295488 (15868 MB) Event timer "LAPIC" quality 600 ACPI APIC Table: <BHYVE BVAPIC > FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs FreeBSD/SMP: 8 package(s) x 1 core(s)
Iām not an src committer. Could someone else please take this on?
if no one else picks this up by tomorrow i can take it, but this isn't at all my usual area of code so we'll need to find someone to review it. (the patch does seem fairly trivial, so hopefully that wouldn't be difficult.)
I can confirm the suggested patch does fix the issue for the n150 processor. Bhyve now reports correctly 4 cores with 1 thread per core. Thank you Jochen for your proposed fix.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=4b1974e9db63d6510406e4ef3e56c250edd2240a commit 4b1974e9db63d6510406e4ef3e56c250edd2240a Author: Jochen Neumeister <joneum@FreeBSD.org> AuthorDate: 2026-08-19 10:07:03 +0000 Commit: Lexi Winter <ivy@FreeBSD.org> CommitDate: 2026-08-19 10:28:33 +0000 vmm: Emulate CPUID leaf 1Fh for guests On an Intel N150 host a guest started with sockets=1, cores=4, threads=1 reports "1 package(s) x 2 core(s) x 2 hardware threads" instead of four cores with one thread each, while the host itself detects its topology correctly. A FreeBSD guest picks the topology leaf in topo_probe_intel_0xb(), sys/x86/x86/mp_x86.c, and since 6badb512a94d it prefers leaf 1Fh over leaf 0Bh whenever cpu_high is 1Fh or higher. bhyve passes leaf 0 through unmodified, so the guest sees the maximum basic leaf of the host, which is 1Fh or above on Alder Lake and newer, and takes that path. x86_emulate_cpuid(), sys/amd64/vmm/x86.c, derives the topology from vm_get_topology() for leaves 1, 4 and 0Bh, but has no case for 1Fh, so the request ends up in default_leaf and the host values are returned verbatim. The guest therefore enumerates the topology of the host: with an SMT shift of 1 in the host's leaf 1Fh and four vCPUs this gives core_id_shift = 1 and pkg_id_shift = 2, which is exactly the reported 2 cores x 2 threads. Hosts whose maximum basic leaf is below 1Fh are unaffected, as the request is clamped to cpu_high before the switch statement. Leaf 1Fh uses the same level encoding as leaf 0Bh for the SMT and the core level, so handle both leaves in the same case. The module, tile and die levels are not emulated and terminate the enumeration, exactly as they already do for leaf 0Bh. PR: 297475 MFC after: 1 week Reported by: Richard Straka <fntms@pryse.net> Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D58885 sys/amd64/vmm/x86.c | 5 ++++- sys/amd64/vmm/x86.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
A commit in branch stable/15 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=8a4fcb694526fdb64709e0382d92053a9d71e49a commit 8a4fcb694526fdb64709e0382d92053a9d71e49a Author: Jochen Neumeister <joneum@FreeBSD.org> AuthorDate: 2026-08-19 10:07:03 +0000 Commit: Lexi Winter <ivy@FreeBSD.org> CommitDate: 2026-08-26 09:56:32 +0000 vmm: Emulate CPUID leaf 1Fh for guests On an Intel N150 host a guest started with sockets=1, cores=4, threads=1 reports "1 package(s) x 2 core(s) x 2 hardware threads" instead of four cores with one thread each, while the host itself detects its topology correctly. A FreeBSD guest picks the topology leaf in topo_probe_intel_0xb(), sys/x86/x86/mp_x86.c, and since 6badb512a94d it prefers leaf 1Fh over leaf 0Bh whenever cpu_high is 1Fh or higher. bhyve passes leaf 0 through unmodified, so the guest sees the maximum basic leaf of the host, which is 1Fh or above on Alder Lake and newer, and takes that path. x86_emulate_cpuid(), sys/amd64/vmm/x86.c, derives the topology from vm_get_topology() for leaves 1, 4 and 0Bh, but has no case for 1Fh, so the request ends up in default_leaf and the host values are returned verbatim. The guest therefore enumerates the topology of the host: with an SMT shift of 1 in the host's leaf 1Fh and four vCPUs this gives core_id_shift = 1 and pkg_id_shift = 2, which is exactly the reported 2 cores x 2 threads. Hosts whose maximum basic leaf is below 1Fh are unaffected, as the request is clamped to cpu_high before the switch statement. Leaf 1Fh uses the same level encoding as leaf 0Bh for the SMT and the core level, so handle both leaves in the same case. The module, tile and die levels are not emulated and terminate the enumeration, exactly as they already do for leaf 0Bh. PR: 297475 MFC after: 1 week Reported by: Richard Straka <fntms@pryse.net> Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D58885 (cherry picked from commit 4b1974e9db63d6510406e4ef3e56c250edd2240a) sys/amd64/vmm/x86.c | 5 ++++- sys/amd64/vmm/x86.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)