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
Message: Re: Reduce timing overhead of EXPLAIN ANALYZE using rdtsc?

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