Index | Thread | Search

From:
ssnf <ssnf@ssnf.xyz>
Subject:
[PATCH 2/6] vmd: emulate i8253 square-wave counter correctly
To:
tech@openbsd.org
Cc:
ssnf <ssnf@ssnf.xyz>
Date:
Sat, 22 Aug 2026 19:02:43 +0000

Download raw body.

Thread
In mode 3, the visible PIT counter decrements by two per input clock.
vmd currently subtratcs one, causing guests to measure the TSC at
approximately twice its actual frequency.

Linux/KVM does the same 2*d treatment for mode 3.
---
 usr.sbin/vmd/i8253.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/usr.sbin/vmd/i8253.c b/usr.sbin/vmd/i8253.c
index 2e6c605b12d..decc8f8543d 100644
--- a/usr.sbin/vmd/i8253.c
+++ b/usr.sbin/vmd/i8253.c
@@ -138,6 +138,8 @@ i8253_do_readback(uint32_t data)
 				timespecsub(&now, &i8253_channel[i].ts, &delta);
 				ns = delta.tv_sec * 1000000000 + delta.tv_nsec;
 				ticks = ns / NS_PER_TICK;
+				if (i8253_channel[i].mode == TIMER_SQWAVE)
+					ticks *= 2;
 				if (i8253_channel[i].start)
 					i8253_channel[i].olatch =
 					    i8253_channel[i].start -
@@ -256,6 +258,8 @@ vcpu_exit_i8253(struct vm_run_params *vrp)
 				    &delta);
 				ns = delta.tv_sec * 1000000000 + delta.tv_nsec;
 				ticks = ns / NS_PER_TICK;
+				if (i8253_channel[sel].mode == TIMER_SQWAVE)
+					ticks *= 2;
 				if (i8253_channel[sel].start) {
 					i8253_channel[sel].olatch =
 					    i8253_channel[sel].start -
-- 
2.51.0