From cab22e5a4ad5a24ca8c2fe4cf43257d86ac4257c Mon Sep 17 00:00:00 2001 From: vasilito Date: Wed, 5 Aug 2026 14:22:28 +0300 Subject: [PATCH] docs: append REGRESSION + REMEDY record for task-8 ps2d read-to-string regression Root cause: std::fs::read_to_string loops forever on kernel scheme /scheme/serio/present (serio kread for HandleKind::Present never produces EOF). Fix: bounded single-byte read in ps2d main.rs (commit aeb2df8e on submodule/base branch). 14/14 host tests green. QEMU gate expected: ps2d startup log BEFORE notify-wait ticks, no kill line. --- .../task-8-ryzen-7000-x670e-compat.txt | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/.omo/evidence/task-8-ryzen-7000-x670e-compat.txt b/.omo/evidence/task-8-ryzen-7000-x670e-compat.txt index 648a2ba4e7..634cdbf1d7 100644 --- a/.omo/evidence/task-8-ryzen-7000-x670e-compat.txt +++ b/.omo/evidence/task-8-ryzen-7000-x670e-compat.txt @@ -92,3 +92,61 @@ Single command (no build needed): - No `src/scheme/irq.rs` cpu- path handling touched - No retries/warning noise on absence - No recipe files modified + +--- +## REGRESSION + REMEDY RECORD (2026-08-05, QEMU verification) + +### Root cause + +`std::fs::read_to_string("/scheme/serio/present")` in +`local/sources/base/drivers/input/ps2d/src/main.rs:38` loops forever on +the i8042-present path. The kernel's `SerioScheme::kread` for +`HandleKind::Present` (kernel `src/scheme/serio.rs:146-148`) always +returns the verdict bytes (`b"1\n"` or `b"0\n"`) on every read without +ever producing a zero-byte EOF. `read_to_string` in Rust std reads +until `read()` returns 0, so it enters an infinite read loop — growing +the accumulator string by 3 bytes per iteration — and never returns to +caller code. ps2d blocks in `read_to_string` before any log output or +`daemon.ready()` can execute, so init's 10s notify-wait timeout kills it +with zero diagnostic output ("'ps2d' did not notify readiness within 10s; +killing and skipping"). + +The absent path (kernel verdict "0\n") is equally affected but was not +caught because the QEMU configs used for absent-path testing happened to +not exercise `read_to_string` (or the absent-path tests were host-only +verdict logic tests, not QEMU boots). The host test suite (14/14 GREEN) +tests the verdict DECISION logic in isolation — it does not exercise the +actual `read_to_string` syscall path on a running Redox kernel. + +### Remedy + +Commit `aeb2df8e` on `submodule/base`: + +- **`drivers/input/ps2d/src/main.rs`** — Replaced `std::fs::read_to_string` + with a bounded single-byte read (`read_serio_present()`): opens + `/scheme/serio/present`, reads at most 2 bytes into a stack buffer, + returns the first byte. Only the first byte matters (b'1' = present, + b'0' = absent); the '\n' is discarded. + +- Added a `log::info!` on the present path BEFORE `InputProducer` opens + ("ps2d: PS/2 controller present; starting serio device handshake") so + future boot logs show ps2d's progress through the startup sequence + before any scheme I/O blocking point. + +Host tests: 14/14 GREEN (`cargo test --manifest-path +local/sources/kernel/host-tests/i8042-verdict/Cargo.toml`). All verdict +decision-table tests pass unchanged — the fix only changes the I/O +mechanism, not the decision logic. + +### Expected QEMU gate observable + +On the i8042-present path, the orchestrator's QEMU gate should see: +- **BEFORE** the first `notify-wait 'ps2d' tick` (within ~50ms of + "Started PS/2 driver"): the line + `ps2d: PS/2 controller present; starting serio device handshake`, + followed by `ps2d: registered producer handle, listening on serio/0 + (keyboard) and serio/1 (mouse)`. +- **ABSENT**: the kill line `'ps2d' did not notify readiness within 10s; + killing and skipping`. +- Keyboard input on `/scheme/serio/0` works in QEMU after ps2d's + successful notify.