Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/cpu: Detect FreeBSD Bhyve hypervisor

Detect the Bhyve hypervisor and enable 15-bit MSI support if available.

Detecting Bhyve used to be a purely cosmetic issue of the kernel printing
'Hypervisor detected: Bhyve' at boot time.

But FreeBSD 15.0 will support¹ the 15-bit MSI enlightenment to support
more than 255 vCPUs (http://david.woodhou.se/ExtDestId.pdf) which means
there's now actually some functional reason to do so.

¹ https://github.com/freebsd/freebsd-src/commit/313a68ea20b4

[ bp: Massage, move tail comment ontop. ]

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Ahmed S. Darwish <darwi@linutronix.de>
Link: https://lore.kernel.org/03802f6f7f5b5cf8c5e8adfe123c397ca8e21093.camel@infradead.org

authored by

David Woodhouse and committed by
Borislav Petkov (AMD)
fa1d1171 f83ec76b

+81
+9
arch/x86/Kconfig
··· 879 879 IOT with small footprint and real-time features. More details can be 880 880 found in https://projectacrn.org/. 881 881 882 + config BHYVE_GUEST 883 + bool "Bhyve (BSD Hypervisor) Guest support" 884 + depends on X86_64 885 + help 886 + This option allows to run Linux to recognise when it is running as a 887 + guest in the Bhyve hypervisor, and to support more than 255 vCPUs when 888 + when doing so. More details about Bhyve can be found at https://bhyve.org 889 + and https://wiki.freebsd.org/bhyve/. 890 + 882 891 config INTEL_TDX_GUEST 883 892 bool "Intel TDX (Trust Domain Extensions) - Guest Support" 884 893 depends on X86_64 && CPU_SUP_INTEL
+2
arch/x86/include/asm/hypervisor.h
··· 30 30 X86_HYPER_KVM, 31 31 X86_HYPER_JAILHOUSE, 32 32 X86_HYPER_ACRN, 33 + X86_HYPER_BHYVE, 33 34 }; 34 35 35 36 #ifdef CONFIG_HYPERVISOR_GUEST ··· 65 64 extern const struct hypervisor_x86 x86_hyper_kvm; 66 65 extern const struct hypervisor_x86 x86_hyper_jailhouse; 67 66 extern const struct hypervisor_x86 x86_hyper_acrn; 67 + extern const struct hypervisor_x86 x86_hyper_bhyve; 68 68 extern struct hypervisor_x86 x86_hyper_xen_hvm; 69 69 70 70 extern bool nopv;
+1
arch/x86/kernel/cpu/Makefile
··· 58 58 obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o 59 59 60 60 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o 61 + obj-$(CONFIG_BHYVE_GUEST) += bhyve.o 61 62 obj-$(CONFIG_ACRN_GUEST) += acrn.o 62 63 63 64 obj-$(CONFIG_DEBUG_FS) += debugfs.o
+66
arch/x86/kernel/cpu/bhyve.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * FreeBSD Bhyve guest enlightenments 4 + * 5 + * Copyright © 2025 Amazon.com, Inc. or its affiliates. 6 + * 7 + * Author: David Woodhouse <dwmw2@infradead.org> 8 + */ 9 + 10 + #include <linux/init.h> 11 + #include <linux/export.h> 12 + #include <asm/processor.h> 13 + #include <asm/hypervisor.h> 14 + 15 + static uint32_t bhyve_cpuid_base; 16 + static uint32_t bhyve_cpuid_max; 17 + 18 + #define BHYVE_SIGNATURE "bhyve bhyve " 19 + 20 + #define CPUID_BHYVE_FEATURES 0x40000001 21 + 22 + /* Features advertised in CPUID_BHYVE_FEATURES %eax */ 23 + 24 + /* MSI Extended Dest ID */ 25 + #define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0) 26 + 27 + static uint32_t __init bhyve_detect(void) 28 + { 29 + if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) 30 + return 0; 31 + 32 + bhyve_cpuid_base = cpuid_base_hypervisor(BHYVE_SIGNATURE, 0); 33 + if (!bhyve_cpuid_base) 34 + return 0; 35 + 36 + bhyve_cpuid_max = cpuid_eax(bhyve_cpuid_base); 37 + return bhyve_cpuid_max; 38 + } 39 + 40 + static uint32_t bhyve_features(void) 41 + { 42 + unsigned int cpuid_leaf = bhyve_cpuid_base | CPUID_BHYVE_FEATURES; 43 + 44 + if (bhyve_cpuid_max < cpuid_leaf) 45 + return 0; 46 + 47 + return cpuid_eax(cpuid_leaf); 48 + } 49 + 50 + static bool __init bhyve_ext_dest_id(void) 51 + { 52 + return !!(bhyve_features() & CPUID_BHYVE_FEAT_EXT_DEST_ID); 53 + } 54 + 55 + static bool __init bhyve_x2apic_available(void) 56 + { 57 + return true; 58 + } 59 + 60 + const struct hypervisor_x86 x86_hyper_bhyve __refconst = { 61 + .name = "Bhyve", 62 + .detect = bhyve_detect, 63 + .init.init_platform = x86_init_noop, 64 + .init.x2apic_available = bhyve_x2apic_available, 65 + .init.msi_ext_dest_id = bhyve_ext_dest_id, 66 + };
+3
arch/x86/kernel/cpu/hypervisor.c
··· 45 45 #ifdef CONFIG_ACRN_GUEST 46 46 &x86_hyper_acrn, 47 47 #endif 48 + #ifdef CONFIG_BHYVE_GUEST 49 + &x86_hyper_bhyve, 50 + #endif 48 51 }; 49 52 50 53 enum x86_hypervisor_type x86_hyper_type;