// SPDX-License-Identifier: GPL-2.0 /* * FreeBSD Bhyve guest enlightenments * * Copyright © 2025 Amazon.com, Inc. or its affiliates. * * Author: David Woodhouse */ #include #include #include #include static uint32_t bhyve_cpuid_base; static uint32_t bhyve_cpuid_max; #define BHYVE_SIGNATURE "bhyve bhyve " #define CPUID_BHYVE_FEATURES 0x40000001 /* Features advertised in CPUID_BHYVE_FEATURES %eax */ /* MSI Extended Dest ID */ #define CPUID_BHYVE_FEAT_EXT_DEST_ID (1UL << 0) static uint32_t __init bhyve_detect(void) { if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) return 0; bhyve_cpuid_base = cpuid_base_hypervisor(BHYVE_SIGNATURE, 0); if (!bhyve_cpuid_base) return 0; bhyve_cpuid_max = cpuid_eax(bhyve_cpuid_base); return bhyve_cpuid_max; } static uint32_t bhyve_features(void) { unsigned int cpuid_leaf = bhyve_cpuid_base | CPUID_BHYVE_FEATURES; if (bhyve_cpuid_max < cpuid_leaf) return 0; return cpuid_eax(cpuid_leaf); } static bool __init bhyve_ext_dest_id(void) { return !!(bhyve_features() & CPUID_BHYVE_FEAT_EXT_DEST_ID); } static bool __init bhyve_x2apic_available(void) { 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, };