Index | Thread | Search

From:
Miguel Landaeta <miguel@miguel.cc>
Subject:
[2/5] lapic: verify timer ticks before trusting pre-populated frequency
To:
tech@openbsd.org
Date:
Tue, 9 Jun 2026 13:26:36 +0000

Download raw body.

Thread
  • Miguel Landaeta:

    [2/5] lapic: verify timer ticks before trusting pre-populated frequency

This is a series of commits to expose ACPI tables to vmd guests.
These were committed and tested individually.

They can be reviewed in their entirety here:

https://github.com/openbsd/src/compare/master...nomadium:src:add-support-for-acpi-in-vmd.patch

---
 sys/arch/amd64/amd64/lapic.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c
index b19dcb349e3..4e94c176d90 100644
--- a/sys/arch/amd64/amd64/lapic.c
+++ b/sys/arch/amd64/amd64/lapic.c
@@ -538,8 +538,24 @@ lapic_calibrate_timer(struct cpu_info *ci)
 	u_long s;
 	int i;
 
-	if (lapic_per_second)
-		goto skip_calibration;
+	if (lapic_per_second) {
+		/*
+		 * A frequency was pre-populated from CPU model tables.
+		 * Verify the LAPIC timer actually ticks before trusting it:
+		 * on bare-metal hardware the timer decrements normally, but on
+		 * hypervisors that do not emulate it the initial-count write is
+		 * discarded and the current-count register reads as zero.
+		 */
+		lapic_timer_oneshot(LAPIC_LVTT_M, 0x80000000);
+		s = intr_disable();
+		wait_next_cycle();
+		if (lapic_gettick() != 0) {
+			intr_restore(s);
+			goto skip_calibration;
+		}
+		intr_restore(s);
+		lapic_per_second = 0;
+	}
 
 	if (mp_verbose)
 		printf("%s: calibrating local timer\n", ci->ci_dev->dv_xname);
-- 
2.54.0