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

Miguel Landaeta <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.