xref: /linux/arch/x86/kernel/cpu/bhyve.c (revision a65879b4584f98e6c1b80380f55ca8cfca82cb47)
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 
bhyve_detect(void)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 
bhyve_features(void)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 
bhyve_ext_dest_id(void)50 static bool __init bhyve_ext_dest_id(void)
51 {
52 	return !!(bhyve_features() & CPUID_BHYVE_FEAT_EXT_DEST_ID);
53 }
54 
bhyve_x2apic_available(void)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 };
67