v25-0001-instrumentation-Avoid-CPUID-0x15-0x16-for-Hyperv.patch
application/octet-stream
Filename: v25-0001-instrumentation-Avoid-CPUID-0x15-0x16-for-Hyperv.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v25-0001
Subject: instrumentation: Avoid CPUID 0x15/0x16 for Hypervisor TSC frequency
| File | + | − |
|---|---|---|
| src/port/pg_cpu_x86.c | 8 | 12 |
From bb05e67b6ff2dd1f3674214baf6698d73b1edca0 Mon Sep 17 00:00:00 2001
From: Lukas Fittl <lukas@fittl.com>
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 <lukas@fittl.com>
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