arch/x86/include/asm/hypervisor.h | 2 + arch/x86/kernel/cpu/Makefile | 2 +- arch/x86/kernel/cpu/bhyve.c | 62 +++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/hypervisor.c | 1 + 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/cpu/bhyve.c
From: David Woodhouse <dwmw@amazon.co.uk>
This detects the Bhyve hypervisor and enables 15-bit MSI support if
available.
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
RFC because the CPUID_BHYVE_FEATURES leaf is submitted to FreeBSD in
https://github.com/freebsd/freebsd-src/pull/1797 and not yet merged.
And because I haven't tested this patch at all other than building it.
It's tiny so I didn't put it behind a separate CONFIG_BHYVE_GUEST.
Should I?
arch/x86/include/asm/hypervisor.h | 2 +
arch/x86/kernel/cpu/Makefile | 2 +-
arch/x86/kernel/cpu/bhyve.c | 62 +++++++++++++++++++++++++++++++
arch/x86/kernel/cpu/hypervisor.c | 1 +
4 files changed, 66 insertions(+), 1 deletion(-)
create mode 100644 arch/x86/kernel/cpu/bhyve.c
diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h
index e41cbf2ec41d..9ad86a7d13f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -30,6 +30,7 @@ enum x86_hypervisor_type {
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
X86_HYPER_ACRN,
+ X86_HYPER_BHYVE,
};
#ifdef CONFIG_HYPERVISOR_GUEST
@@ -64,6 +65,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
extern const struct hypervisor_x86 x86_hyper_kvm;
extern const struct hypervisor_x86 x86_hyper_jailhouse;
extern const struct hypervisor_x86 x86_hyper_acrn;
+extern const struct hypervisor_x86 x86_hyper_bhyve;
extern struct hypervisor_x86 x86_hyper_xen_hvm;
extern bool nopv;
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 1e26179ff18c..d4cb04edbacf 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -57,7 +57,7 @@ obj-$(CONFIG_X86_SGX) += sgx/
obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o
-obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o bhyve.o
obj-$(CONFIG_ACRN_GUEST) += acrn.o
obj-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/arch/x86/kernel/cpu/bhyve.c b/arch/x86/kernel/cpu/bhyve.c
new file mode 100644
index 000000000000..6d8d6ba458ef
--- /dev/null
+++ b/arch/x86/kernel/cpu/bhyve.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FreeBSD Bhyve guest enlightenments
+ *
+ * Copyright © 2025 Amazon.com, Inc. or its affiliates.
+ *
+ * Author: David Woodhouse <dwmw2@infradead.org>
+ */
+
+#include <linux/init.h>
+#include <linux/export.h>
+#include <asm/processor.h>
+#include <asm/hypervisor.h>
+
+static uint32_t bhyve_cpuid_base;
+static uint32_t bhyve_cpuid_max;
+
+#define CPUID_BHYVE_FEATURES 1
+
+/* Features advertised in CPUID_BHYVE_FEATURES %eax */
+#define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0) /* MSI Extended Dest ID */
+
+static uint32_t __init bhyve_detect(void)
+{
+ if (boot_cpu_data.cpuid_level < 0 ||
+ !boot_cpu_has(X86_FEATURE_HYPERVISOR))
+ return 0;
+
+ bhyve_cpuid_base = cpuid_base_hypervisor("bhyve bhyve ", 0);
+ if (!bhyve_cpuid_base)
+ return 0;
+
+ bhyve_cpuid_max = cpuid_eax(bhyve_cpuid_max);
+ return bhyve_cpuid_max;
+}
+
+static uint32_t bhyve_features(void)
+{
+ if (bhyve_cpuid_max < bhyve_cpuid_base + CPUID_BHYVE_FEATURES)
+ return 0;
+
+ return cpuid_eax(bhyve_cpuid_base + CPUID_BHYVE_FEATURES);
+}
+
+static bool __init bhyve_ext_dest_id(void)
+{
+ return !!(bhyve_features() & CPUID_BHYVE_FEAT_EXT_DEST_ID);
+}
+
+static bool __init bhyve_x2apic_available(void)
+{
+ /* Bhyve has always supported x2apic */
+ return true;
+}
+
+const struct hypervisor_x86 x86_hyper_bhyve __refconst = {
+ .name = "Bhyve",
+ .detect = bhyve_detect,
+ .init.init_platform = x86_init_noop,
+ .init.x2apic_available = bhyve_x2apic_available,
+ .init.msi_ext_dest_id = bhyve_ext_dest_id,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 553bfbfc3a1b..157cf9edeb35 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -36,6 +36,7 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] =
#endif
&x86_hyper_vmware,
&x86_hyper_ms_hyperv,
+ &x86_hyper_bhyve,
#ifdef CONFIG_KVM_GUEST
&x86_hyper_kvm,
#endif
--
2.49.0
On Mon, Aug 11, 2025 at 01:16:42PM +0200, David Woodhouse wrote: > From: David Woodhouse <dwmw@amazon.co.uk> > > This detects the Bhyve hypervisor Users of this are? Wikipedia says it already supports Linux :-P > and enables 15-bit MSI support if > available. > > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> > --- > RFC because the CPUID_BHYVE_FEATURES leaf is submitted to FreeBSD in Which makes it, what, 0x4000_0001? I presume there's an agreement among all the hypervisors...? > https://github.com/freebsd/freebsd-src/pull/1797 and not yet merged. > And because I haven't tested this patch at all other than building it. > > It's tiny so I didn't put it behind a separate CONFIG_BHYVE_GUEST. > Should I? Yeah, please do. > +/* Features advertised in CPUID_BHYVE_FEATURES %eax */ > +#define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0) /* MSI Extended Dest ID */ > + > +static uint32_t __init bhyve_detect(void) > +{ > + if (boot_cpu_data.cpuid_level < 0 || > + !boot_cpu_has(X86_FEATURE_HYPERVISOR)) cpu_feature_enabled() -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette
On Thu, 2025-08-14 at 12:15 +0200, Borislav Petkov wrote: > On Mon, Aug 11, 2025 at 01:16:42PM +0200, David Woodhouse wrote: > > From: David Woodhouse <dwmw@amazon.co.uk> > > > > This detects the Bhyve hypervisor > > Users of this are? FreeBSD and Illumos (and some other *BSD) users, presumably? > Wikipedia says it already supports Linux :-P It does, but Linux doesn't support *it*. Which mostly didn't matter because all that's missing was a cosmetic 'Hypervisor detected: Bhyve' in the kernel log. But now it's no longer just cosmetic because... > > and enables 15-bit MSI support if available. I have finally written up some proper documentation for that 15-bit MSI enlightenment, btw: http://david.woodhou.se/ExtDestId.pdf > > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> > > --- > > RFC because the CPUID_BHYVE_FEATURES leaf is submitted to FreeBSD in > > Which makes it, what, 0x4000_0001? > > I presume there's an agreement among all the hypervisors...? There is no such agreement about CPUID; by *coincidence* most of them seem to use 0x4000_0?01 as their feature leaf, but the feature bits in each such leaf are completely different and the guest doesn't look at a given leaf unless it knows that specific hypervisor. Which is why the 15-bit enlightenment is advertised differently by each hypervisor despite being precisely the same enlightenment across them all. (Digressing a little... the slight exception is the 0x4000_0010 leaf which by coincidence I have *also* been looking at this week. VMware proposed a common convention in https://lkml.org/lkml/2008/10/1/246 but it was shot down in flames. However, the 'timing info' leaf didn't quite die, and both XNU and FreeBSD guests actually look for it at 0x4000_0010 under *all* hypervisors. And it even got added in the EC2 Nitro hypervisor. I have patches pending to make KVM support it on both host and guest side, which I'll post shortly.) > > https://github.com/freebsd/freebsd-src/pull/1797 and not yet merged. > > And because I haven't tested this patch at all other than building it. > > > > It's tiny so I didn't put it behind a separate CONFIG_BHYVE_GUEST. > > Should I? > > Yeah, please do. > > > +/* Features advertised in CPUID_BHYVE_FEATURES %eax */ > > +#define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0) /* MSI Extended Dest ID */ > > + > > +static uint32_t __init bhyve_detect(void) > > +{ > > + if (boot_cpu_data.cpuid_level < 0 || > > + !boot_cpu_has(X86_FEATURE_HYPERVISOR)) > > cpu_feature_enabled() > Ack, v2 coming up shortly. Thanks.
On Thu, 14 Aug 2025, David Woodhouse wrote: > On Thu, 2025-08-14 at 12:15 +0200, Borislav Petkov wrote: > > > > > Which makes it, what, 0x4000_0001? > > > > I presume there's an agreement among all the hypervisors...? > > There is no such agreement about CPUID; by *coincidence* most of them > seem to use 0x4000_0?01 as their feature leaf, but the feature bits in > each such leaf are completely different and the guest doesn't look at a > given leaf unless it knows that specific hypervisor. Which is why the > 15-bit enlightenment is advertised differently by each hypervisor > despite being precisely the same enlightenment across them all. > For what it takes, such hypervisor leaves, in the 0x40000000 range, will be converted by the ongoing x86-cpuid-db CPUID parser work at some point. (Another iteration of the CPUID parser is to be posted today.) Thanks, Ahmed
On Mon, 2025-08-11 at 13:16 +0200, David Woodhouse wrote: > From: David Woodhouse <dwmw@amazon.co.uk> > > This detects the Bhyve hypervisor and enables 15-bit MSI support if > available. > > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> > --- > RFC because the CPUID_BHYVE_FEATURES leaf is submitted to FreeBSD in > https://github.com/freebsd/freebsd-src/pull/1797 and not yet merged. > And because I haven't tested this patch at all other than building it. Now merged and should be in FreeBSD 15.0 release. Thanks, Colin! https://github.com/freebsd/freebsd-src/commit/4322d597453d6 > It's tiny so I didn't put it behind a separate CONFIG_BHYVE_GUEST. > Should I? > > arch/x86/include/asm/hypervisor.h | 2 + > arch/x86/kernel/cpu/Makefile | 2 +- > arch/x86/kernel/cpu/bhyve.c | 62 +++++++++++++++++++++++++++++++ > arch/x86/kernel/cpu/hypervisor.c | 1 + > 4 files changed, 66 insertions(+), 1 deletion(-) > create mode 100644 arch/x86/kernel/cpu/bhyve.c > > diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h > index e41cbf2ec41d..9ad86a7d13f6 100644 > --- a/arch/x86/include/asm/hypervisor.h > +++ b/arch/x86/include/asm/hypervisor.h > @@ -30,6 +30,7 @@ enum x86_hypervisor_type { > X86_HYPER_KVM, > X86_HYPER_JAILHOUSE, > X86_HYPER_ACRN, > + X86_HYPER_BHYVE, > }; > > #ifdef CONFIG_HYPERVISOR_GUEST > @@ -64,6 +65,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv; > extern const struct hypervisor_x86 x86_hyper_kvm; > extern const struct hypervisor_x86 x86_hyper_jailhouse; > extern const struct hypervisor_x86 x86_hyper_acrn; > +extern const struct hypervisor_x86 x86_hyper_bhyve; > extern struct hypervisor_x86 x86_hyper_xen_hvm; > > extern bool nopv; > diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile > index 1e26179ff18c..d4cb04edbacf 100644 > --- a/arch/x86/kernel/cpu/Makefile > +++ b/arch/x86/kernel/cpu/Makefile > @@ -57,7 +57,7 @@ obj-$(CONFIG_X86_SGX) += sgx/ > > obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o > > -obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o > +obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o bhyve.o > obj-$(CONFIG_ACRN_GUEST) += acrn.o > > obj-$(CONFIG_DEBUG_FS) += debugfs.o > diff --git a/arch/x86/kernel/cpu/bhyve.c b/arch/x86/kernel/cpu/bhyve.c > new file mode 100644 > index 000000000000..6d8d6ba458ef > --- /dev/null > +++ b/arch/x86/kernel/cpu/bhyve.c > @@ -0,0 +1,62 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * FreeBSD Bhyve guest enlightenments > + * > + * Copyright © 2025 Amazon.com, Inc. or its affiliates. > + * > + * Author: David Woodhouse <dwmw2@infradead.org> > + */ > + > +#include <linux/init.h> > +#include <linux/export.h> > +#include <asm/processor.h> > +#include <asm/hypervisor.h> > + > +static uint32_t bhyve_cpuid_base; > +static uint32_t bhyve_cpuid_max; > + > +#define CPUID_BHYVE_FEATURES 1 > + > +/* Features advertised in CPUID_BHYVE_FEATURES %eax */ > +#define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0) /* MSI Extended Dest ID */ > + > +static uint32_t __init bhyve_detect(void) > +{ > + if (boot_cpu_data.cpuid_level < 0 || > + !boot_cpu_has(X86_FEATURE_HYPERVISOR)) > + return 0; > + > + bhyve_cpuid_base = cpuid_base_hypervisor("bhyve bhyve ", 0); > + if (!bhyve_cpuid_base) > + return 0; > + > + bhyve_cpuid_max = cpuid_eax(bhyve_cpuid_max); > + return bhyve_cpuid_max; > +} > + > +static uint32_t bhyve_features(void) > +{ > + if (bhyve_cpuid_max < bhyve_cpuid_base + CPUID_BHYVE_FEATURES) > + return 0; > + > + return cpuid_eax(bhyve_cpuid_base + CPUID_BHYVE_FEATURES); > +} > + > +static bool __init bhyve_ext_dest_id(void) > +{ > + return !!(bhyve_features() & CPUID_BHYVE_FEAT_EXT_DEST_ID); > +} > + > +static bool __init bhyve_x2apic_available(void) > +{ > + /* Bhyve has always supported x2apic */ > + return true; > +} > + > +const struct hypervisor_x86 x86_hyper_bhyve __refconst = { > + .name = "Bhyve", > + .detect = bhyve_detect, > + .init.init_platform = x86_init_noop, > + .init.x2apic_available = bhyve_x2apic_available, > + .init.msi_ext_dest_id = bhyve_ext_dest_id, > +}; > diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c > index 553bfbfc3a1b..157cf9edeb35 100644 > --- a/arch/x86/kernel/cpu/hypervisor.c > +++ b/arch/x86/kernel/cpu/hypervisor.c > @@ -36,6 +36,7 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] = > #endif > &x86_hyper_vmware, > &x86_hyper_ms_hyperv, > + &x86_hyper_bhyve, > #ifdef CONFIG_KVM_GUEST > &x86_hyper_kvm, > #endif
© 2016 - 2025 Red Hat, Inc.