Add support for obtaining TSC frequency from VMWare
When running as a VMware guest, if CPUID leaf 0x40000010 exists, it provides:
EAX: TSC frequency (in kHz)
EBX: APIC frequency (in kHz)
When running as a VMware guest, we should utilize this to obtain the TSC frequency over using emulated devices such as an HPET or PIT.
There is also a VMware call
VMWARE_HVCMD_GETTSCFREQ that returns the TSC frequency as a 64-bit int (split into two 32-bit values) for older VMWare versions.
Unfortunately, none of the sources (nor did a search) reveal which versions of VMware provide the CPUID method vs. the VMware hyper call. Given the sources describing the VMware CPUID leaf are over 13 years old, it suggests that at minimum any VMware version 13 years old (or newer) should support the CPUID method, and any version that would exclusively have the hyper call method would be at least 13 years old. Additionally, since actual documentation on the hyper call doesn't seem to be readily available, it's continuing availability in the future would suggest it's probably only worth supporting the CPUID method, and not the VMWare hyper call method.
That is to say, this change will only add support for using the VMware CPUID leaf 0x40000010 to identify the TSC frequency. This will preferentially be used over the emulated HPET or PIT. If someone is running a version of VMware that is sufficiently vintage such that the CPUID leaf 0x40000010 is not supported, the system will fall back to using the HPET or if that fails, the PIT to calibrate the TSC (as occurs prior to this change).
Updated by Jason King 8 months ago
Testing on an OmniOS VM with this change, I verified that the VMWare source was chosen during boot (using mdb). I then compared the reported TSC frequency from tsc_calibrate_vmware to the known CPU frequency of the CPUs (since the two pretty much always match these days). The values matched within the expected tolerance (e.g. the model string is '2.70Ghz' vs a reported '2,693,509,000 Hz'.
Additionally, the reported value matches the PIT measured frequency within 0.001% (2693509000 reported vs 2693469152 measured with the PIT). However, this was done when the VMWare machine was fairly lightly loaded -- it wouldn't be unexpected to see a larger difference on a highly loaded VMWare machine where the emulated PIT would produce a less reliable value (though I'm not sure if I'd have the ability to deliberately load this VMWare machine to prove that out).
Updated by Electric Monk 8 months ago
- Status changed from New to Closed
- % Done changed from 0 to 100
commit 04ddedda9041ffd4ef5d0eed5c8ba1f101017fd7 Author: Jason King <email@example.com> Date: 2021-09-23T03:27:42.000Z 13963 Add support for obtaining TSC frequency from VMWare Reviewed by: Vitaliy Gusev <firstname.lastname@example.org> Reviewed by: Andy Fiddaman <email@example.com> Reviewed by: Reviewed by: Toomas Soome <firstname.lastname@example.org> Approved by: Gordon Ross <email@example.com>