clock diagnostics for issue #3: probe, VM sanity scenario, fix plan

The qemu/ device sim answered the first question off-board: the same
kernel family under -M virt gives musl vDSO rate ratio 0.99963 — the
generic 6.18 armv7 vDSO is correct, so the board symptom is RV1106
register state (CNTFRQ/CNTVOFF, firmware-owned, secure-world boot chain).

- qemu/tests/clockprobe: interval-based musl probe separating RATE error
  (CNTFRQ) from boot OFFSET (CNTVOFF) — the original single absolute
  sample cannot distinguish them.
- qemu/tests/clock-sanity.sh: VM regression guard asserting the vDSO rate
  within 1% (PASSES: 1.00026); cross-builds the probe and stages it as
  payload itself.
- kernel/rv1106-enablement/timer/PLAN.md: the DT fix
  (arm,cpu-registers-not-fw-configured + measured clock-frequency on the
  board dts) gated on the two bench measurements; c8a3 is currently
  physically dark, needs hands at the bench.
- clockprobe joins the CI test loop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HUayid7W5w7jBdb9Rrj1K
This commit is contained in:
BFE Engineering
2026-08-30 09:49:50 -06:00
co-authored by Claude Fable 5
parent ff62991e8d
commit 1d7dec167e
6 changed files with 200 additions and 1 deletions
+16
View File
@@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "clockprobe"
version = "0.1.0"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "clockprobe"
version = "0.1.0"
edition = "2021"
description = "Interval-based monotonic-clock rate probe: compares musl/vDSO CLOCK_MONOTONIC(+_RAW) against /proc/uptime so rate errors and boot-time offsets (CNTVOFF) separate cleanly. Diagnostic for issue #3."
license = "GPL-2.0-only"
[dependencies]
libc = "0.2"
[profile.release]
strip = true
+25
View File
@@ -0,0 +1,25 @@
// Differential clock probe for warden-sdk issue #3: compares the musl/vDSO
// CLOCK_MONOTONIC rate against the kernel's own /proc/uptime over a fixed
// interval, so boot-time offsets cancel and only the RATE ratio remains.
use std::{fs, thread, time::Duration};
fn mono(clock: libc::clockid_t) -> f64 {
let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
unsafe { libc::clock_gettime(clock, &mut ts) };
ts.tv_sec as f64 + ts.tv_nsec as f64 / 1e9
}
fn uptime() -> f64 {
fs::read_to_string("/proc/uptime").unwrap()
.split_whitespace().next().unwrap().parse().unwrap()
}
fn main() {
let interval = 10.0;
let (m0, r0, u0) = (mono(libc::CLOCK_MONOTONIC), mono(libc::CLOCK_MONOTONIC_RAW), uptime());
thread::sleep(Duration::from_secs_f64(interval));
let (m1, r1, u1) = (mono(libc::CLOCK_MONOTONIC), mono(libc::CLOCK_MONOTONIC_RAW), uptime());
let (dm, dr, du) = (m1 - m0, r1 - r0, u1 - u0);
println!("CLOCKPROBE monotonic={dm:.4} raw={dr:.4} uptime={du:.4} ratio_mono={:.5} ratio_raw={:.5}", dm / du, dr / du);
println!("CLOCKPROBE abs monotonic={m1:.2} uptime={u1:.2} abs_ratio={:.5}", m1 / u1);
}