Index | Thread | Search

From:
ssnf <ssnf@ssnf.xyz>
Subject:
[PATCH 3/6] vmd: handle zero i8253 counter value as 65536
To:
tech@openbsd.org
Cc:
ssnf <ssnf@ssnf.xyz>
Date:
Sat, 22 Aug 2026 19:02:44 +0000

Download raw body.

Thread
The PIT uses a 16-bit programmed count, but in binary mode a
programmed value of zero represents 65536 clocks, allowing the
full 1-65536 divisor range.

Vmd currently converts zero to 0xffff, producing a divisor of
65535 instead.

Start must therefore be wider than 16 bits so the emulation can
represent 65536 internally, while the guest-visible latch remains
16 bits.
---
 usr.sbin/vmd/i8253.c | 4 ++--
 usr.sbin/vmd/i8253.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/usr.sbin/vmd/i8253.c b/usr.sbin/vmd/i8253.c
index decc8f8543d..917def18b75 100644
--- a/usr.sbin/vmd/i8253.c
+++ b/usr.sbin/vmd/i8253.c
@@ -167,7 +167,7 @@ uint8_t
 vcpu_exit_i8253_misc(struct vm_run_params *vrp)
 {
 	struct vm_exit *vei = vrp->vrp_exit;
-	uint16_t cur;
+	uint32_t cur;
 	uint64_t ns, ticks;
 	struct timespec now, delta;
 
@@ -297,7 +297,7 @@ vcpu_exit_i8253(struct vm_run_params *vrp)
 				i8253_channel[sel].last_w = 0;
 
 				if (i8253_channel[sel].start == 0)
-					i8253_channel[sel].start = 0xffff;
+					i8253_channel[sel].start = 0x10000;
 
 				clock_gettime(CLOCK_MONOTONIC,
 				    &i8253_channel[sel].ts);
diff --git a/usr.sbin/vmd/i8253.h b/usr.sbin/vmd/i8253.h
index c938c42d4cb..493a295c84a 100644
--- a/usr.sbin/vmd/i8253.h
+++ b/usr.sbin/vmd/i8253.h
@@ -31,7 +31,7 @@
 /* i8253 registers */
 struct i8253_channel {
 	struct timespec ts;	/* timer start time */
-	uint16_t start;		/* starting value */
+	uint32_t start;		/* starting value */
 	uint16_t olatch;	/* output latch */
 	uint16_t ilatch;	/* input latch */
 	uint8_t last_r;		/* last read byte (MSB/LSB) */
-- 
2.51.0