From bb05e67b6ff2dd1f3674214baf6698d73b1edca0 Mon Sep 17 00:00:00 2001 From: Lukas Fittl Date: Wed, 8 Apr 2026 20:48:14 -0700 Subject: [PATCH v25 1/2] 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 that is not trustworthy and can report a wildly incorrect frequency, like 7 kHz when the actual calibrated frequencty is 2.5 GHz. Per report from buildfarm member drongo. Author: Lukas Fittl Discussion: https://www.postgresql.org/message-id/flat/jr4hk2sxhqcfpb67ftz5g4vw33nm67cgf7go3wwmqsafu5aclq%405m67ukuhyszz#2fdfd95b6a4a74410196999818e16cfc --- src/port/pg_cpu_x86.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/port/pg_cpu_x86.c b/src/port/pg_cpu_x86.c index 32d0cecbe2c..ad8011b63e3 100644 --- a/src/port/pg_cpu_x86.c +++ b/src/port/pg_cpu_x86.c @@ -165,19 +165,15 @@ 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 itself using specialized CPUID registers. + * + * Note it is not safe to utilize the regular 0x15/0x16 CPUID registers in + * a virtual machine, as it has been observed to be wildly incorrect. + */ 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 -- 2.47.1