mirror of
https://github.com/postgres/postgres.git
synced 2026-05-28 04:35:45 -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};
|
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))
|
if (x86_feature_available(PG_HYPERVISOR))
|
||||||
{
|
return x86_hypervisor_tsc_frequency_khz();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On modern Intel CPUs, the TSC is implemented by invariant timekeeping
|
* On modern Intel CPUs, the TSC is implemented by invariant timekeeping
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue