mirror of
https://github.com/postgres/postgres.git
synced 2026-04-15 14:07:46 -04:00
instrumentation: Avoid CPUID 0x15/0x16 for Hypervisor TSC frequency
This restricts the retrieval of the TSC frequency whilst under a Hypervisor to either Hypervisor-specific CPUID registers (0x40000010), or TSC calibration. We previously allowed retrieving from the traditional CPUID registers for TSC frequency (0x15/0x16) like on bare metal, but it turns out that they are not trustworthy when virtualized and can report wildly incorrect frequencies, like 7 kHz when the actual calibrated frequencty is 2.5 GHz. Per report from buildfarm member drongo. Author: Lukas Fittl <lukas@fittl.com> Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/jr4hk2sxhqcfpb67ftz5g4vw33nm67cgf7go3wwmqsafu5aclq%405m67ukuhyszz
This commit is contained in:
parent
60165db6e1
commit
7fc36c5db5
1 changed files with 9 additions and 12 deletions
|
|
@ -165,19 +165,16 @@ x86_tsc_frequency_khz(void)
|
|||
{
|
||||
unsigned int reg[4] = {0};
|
||||
|
||||
/*
|
||||
* If we're inside a virtual machine, try to fetch the TSC frequency from
|
||||
* the hypervisor, using a hypervisor specific method.
|
||||
*
|
||||
* Note it is not safe to utilize the regular 0x15/0x16 CPUID registers
|
||||
* (i.e. the logic below) in virtual machines, as they have been observed
|
||||
* to be wildly incorrect when virtualized.
|
||||
*/
|
||||
if (x86_feature_available(PG_HYPERVISOR))
|
||||
{
|
||||
uint32 freq = x86_hypervisor_tsc_frequency_khz();
|
||||
|
||||
/*
|
||||
* If the hypervisor specific logic didn't figure out the frequency,
|
||||
* it's possible (although not likely, as often that's hidden from
|
||||
* guests) that the non-virtualized logic can figure out the
|
||||
* frequency.
|
||||
*/
|
||||
if (freq > 0)
|
||||
return freq;
|
||||
}
|
||||
return x86_hypervisor_tsc_frequency_khz();
|
||||
|
||||
/*
|
||||
* On modern Intel CPUs, the TSC is implemented by invariant timekeeping
|
||||
|
|
|
|||
Loading…
Reference in a new issue