git: 4a432614f68c - main - TSC: Use 0x40000010 CPUID leaf for all VM types
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 15 Jan 2022 01:30:35 UTC
The branch main has been updated by cperciva:
URL: https://cgit.FreeBSD.org/src/commit/?id=4a432614f68cf35879dbb4ebef089f5b8db95334
commit 4a432614f68cf35879dbb4ebef089f5b8db95334
Author: Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2022-01-04 07:28:36 +0000
Commit: Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2022-01-15 01:30:17 +0000
TSC: Use 0x40000010 CPUID leaf for all VM types
While this CPUID leaf was originally only used by VMWare, other
hypervisors now also use it to announce the TSC frequency to guests.
This speeds up the boot process by 100 ms in EC2 and other systems,
by allowing the early calibration DELAY to be skipped.
Reviewed by: markj
Sponsored by: https://www.patreon.com/cperciva
---
sys/x86/x86/tsc.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c
index 75c452f365cf..317be8979feb 100644
--- a/sys/x86/x86/tsc.c
+++ b/sys/x86/x86/tsc.c
@@ -121,19 +121,29 @@ static struct timecounter tsc_timecounter = {
#endif
};
+static int
+tsc_freq_cpuid_vm(void)
+{
+ u_int regs[4];
+
+ if (vm_guest == VM_GUEST_NO)
+ return (false);
+ if (hv_high < 0x40000010)
+ return (false);
+ do_cpuid(0x40000010, regs);
+ tsc_freq = (uint64_t)(regs[0]) * 1000;
+ tsc_early_calib_exact = 1;
+ return (true);
+}
+
static void
tsc_freq_vmware(void)
{
u_int regs[4];
- if (hv_high >= 0x40000010) {
- do_cpuid(0x40000010, regs);
- tsc_freq = regs[0] * 1000;
- } else {
- vmware_hvcall(VMW_HVCMD_GETHZ, regs);
- if (regs[1] != UINT_MAX)
- tsc_freq = regs[0] | ((uint64_t)regs[1] << 32);
- }
+ vmware_hvcall(VMW_HVCMD_GETHZ, regs);
+ if (regs[1] != UINT_MAX)
+ tsc_freq = regs[0] | ((uint64_t)regs[1] << 32);
tsc_early_calib_exact = 1;
}
@@ -305,6 +315,9 @@ probe_tsc_freq(void)
break;
}
+ if (tsc_freq_cpuid_vm())
+ return;
+
if (vm_guest == VM_GUEST_VMWARE) {
tsc_freq_vmware();
return;