aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2024-02-02 10:36:52 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2024-02-22 10:08:05 +0000
commit4401b0685163c0a460c1f41b107225b0b0ee2062 (patch)
tree349714993e718fc3bac95e6901d6a3de271eacc3
parentf0cf86c075cda435c1481fe59440d6c4bbf855dd (diff)
downloadsrc-4401b0685163c0a460c1f41b107225b0b0ee2062.tar.gz
src-4401b0685163c0a460c1f41b107225b0b0ee2062.zip
x86/cpu: introduce an optional hook for early hypervisor initialization
Hypervisor detection is done very early on x86, and so can be used to also do some very early hypervisor related initialization. Such initialization is required when running as a Xen PVH guest, as for example the PIT needs to be replaced with an hypervisor based timecounter. Introduce an optional hook that gets called as part of the early hypervisor detection. No functional change intended. Sponsored by: Cloud Software Group Reviewed by: markj kib Differential revision: https://reviews.freebsd.org/D43763
-rw-r--r--sys/x86/x86/identcpu.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c
index df24c5bddffd..6df138bccba1 100644
--- a/sys/x86/x86/identcpu.c
+++ b/sys/x86/x86/identcpu.c
@@ -1343,6 +1343,7 @@ SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL);
static struct {
const char *vm_cpuid;
int vm_guest;
+ void (*init)(void);
} vm_cpuids[] = {
{ "XenVMMXenVMM", VM_GUEST_XEN }, /* XEN */
{ "Microsoft Hv", VM_GUEST_HV }, /* Microsoft Hyper-V */
@@ -1355,6 +1356,7 @@ static struct {
static void
identify_hypervisor_cpuid_base(void)
{
+ void (*init_fn)(void) = NULL;
u_int leaf, regs[4];
int i;
@@ -1391,6 +1393,7 @@ identify_hypervisor_cpuid_base(void)
if (strncmp((const char *)&regs[1],
vm_cpuids[i].vm_cpuid, 12) == 0) {
vm_guest = vm_cpuids[i].vm_guest;
+ init_fn = vm_cpuids[i].init;
break;
}
@@ -1423,10 +1426,13 @@ identify_hypervisor_cpuid_base(void)
* preferred.
*/
vm_guest != VM_GUEST_HV)
- return;
+ break;
}
}
}
+
+ if (init_fn != NULL)
+ init_fn();
}
void