From c55e65de5e05b8a3cc3f356e9adb6ce7f7d3e3a5 Mon Sep 17 00:00:00 2001 From: Nexoniarz Date: Sun, 9 Aug 2026 21:05:34 +0200 Subject: [PATCH] memory: the e820 work, and why the extended suite flaps Records the measured effect of the region-based allocator (2.2x on a cold ls, 6 s off the boot), the two pre-existing UEFI blockers found while verifying it, and the three confounds that each produced a confident wrong answer about guest speed in one session. Co-Authored-By: Claude Opus 5 --- .claude/memory/schos-bootcheck-trust.md | 31 +++++++++++++- .claude/memory/schos-uefi-loader.md | 55 +++++++++++++++++++------ 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/.claude/memory/schos-bootcheck-trust.md b/.claude/memory/schos-bootcheck-trust.md index 7c47a09..17c66b0 100644 --- a/.claude/memory/schos-bootcheck-trust.md +++ b/.claude/memory/schos-bootcheck-trust.md @@ -4,7 +4,7 @@ description: bootcheck silently stopped running and five of seven modes asserted metadata: node_type: memory originSessionId: 9d8a2aef-bcf0-47a0-96c6-f706efab4a95 - modified: 2026-08-09T13:55:00.546Z + modified: 2026-08-09T19:05:06.942Z --- **A green run is only green if you counted the checks.** On 2026-08-09 the @@ -45,3 +45,32 @@ of success. Both of these produced clean-looking runs while testing nothing. **How to apply:** after any change to the harness itself, verify the check count, not just the absence of FAIL. + +## The extended suite is timing-fragile on the Fedora laptop + +`Wait-Prompt` waits a fixed **20 s**; measured on this machine with the guest's +own `/proc/uptime`, a cold `ls /bin | wc -l` takes **23 s** and took **51 s** +before the e820 work. When it overruns, the script sleeps 2 s and types anyway, +so the next command lands in a busy shell and the transcript interleaves — and +the check that fails is then some *later* one whose output is no longer +adjacent to its command. `yes writes through a pipe` failed this way while +`y`/`y` were plainly correct in the transcript. Treat a single FAIL in +`-Fb -Tty -Usb -Sock -Evdev -Ps` as suspect until the transcript is read. + +**Leaked QEMU made this worse and is now fixed** (commit 4e0478c): the +`finally` cannot run when the *script* is killed, so QEMU outlived it and, under +TCG, taxed every later run. Each run now records its pid and reaps the previous +one's orphan. + +## Measuring anything about guest speed + +Do not use host wall clock, and do not compare runs made minutes apart. Three +confounds each produced a confident wrong answer in one session: + +1. **Stray QEMU** pinning a core (see above). +2. **`build/schfs.img` ages** — it accumulates writes across boots. Delete and + `make build/schfs.img` before every timed boot. +3. **Ordering / host drift** — alternate the variants and run each twice. + +Time it from inside: `cat /proc/uptime` either side of the command. The guest's +tick does not care what the host is doing. See [[schunix-verify-by-driving-shell]]. diff --git a/.claude/memory/schos-uefi-loader.md b/.claude/memory/schos-uefi-loader.md index 63a1f5c..43dafa0 100644 --- a/.claude/memory/schos-uefi-loader.md +++ b/.claude/memory/schos-uefi-loader.md @@ -1,8 +1,10 @@ --- name: schos-uefi-loader -description: boot/uefi works under OVMF; the SCH64 entry, the GDT trap, and the one open bug (e820 fragmentation) -metadata: - node_type: project +description: "boot/uefi works under OVMF; the SCH64 entry, the GDT trap, and the one open bug (e820 fragmentation)" +metadata: + node_type: memory + originSessionId: d4821aa9-2e49-40da-91e7-90ef9ed9997e + modified: 2026-08-09T19:05:15.325Z --- **`boot/uefi/` boots.** `make uefi`, `make esp`, `make qemu-uefi`. Verified @@ -42,17 +44,46 @@ arriving in long mode is still on the firmware's descriptors; the first thing needing the kernel's own selectors faulted with `unexpected trap 13 ... cs=38`, a long way from the cause. -## Open bug: the memory map +## The memory map — fixed 2026-08-09 -`e820_init` takes the usable run **containing the kernel**. Under OVMF that run -ends at 8 MB — the firmware places an ACPI NVS region at 0x800000, so it is -genuinely fragmented. The loader's map is truthful and untruncated (21 entries); -the one-contiguous-run assumption is BIOS-shaped. +`e820_init` used to take the usable run **containing the kernel**, which under +OVMF ends at 8 MB because the firmware puts an ACPI NVS region at 0x800000. +That failed the `PHYSTOP_MIN` check, so the kernel fell back to asserting +224 MB it had not measured and then freed straight through the reserved hole. -**Fix: have the kernel free each usable region rather than one range.** That -touches `kalloc`/`freerange` and `kinit1`, which is the most safety-critical -code in the tree — it deserves its own change with both boot paths verified, -not the tail of a session. +The kernel now keeps the usable regions as a **list** (`mem_usable[]` / +`nmem_usable` in memlayout.h) as well as a top address, and `kinit1` frees each +one clipped to the window `main()` passes in. `PHYSTOP` still means exactly what +it did, so no call site changed. `phystop` comes from the **largest** region, +not the highest, because the DMA arena is carved off the top of it and must be +contiguous; a smaller region above it is deliberately left unfreed rather than +raising the bound past a hole. + +Result: 1018 MB in 7 regions under OVMF, 1023 MB in 2 under BIOS. + +**It is also a large speedup, which was not the goal and is worth knowing.** +Measured from inside the guest (`/proc/uptime`, fresh image each boot, +alternating rounds): boot to prompt **14.8 s vs 21.2 s**, and a cold +`ls /bin | wc -l` **23.6 s vs 51.2 s** — 2.2x. Both rounds agreed within +0.3 s. So if the allocator ever looks slow again, this is the baseline to +compare against. + +## What still stops a full UEFI boot + +Two separate, pre-existing problems — neither is the memory map, and both +predate the e820 work (the unfixed kernel triple faults in the same place): + +1. **virtio-gpu's BAR lands above 4 GB.** OVMF assigns the 64-bit BAR high; + the first MMIO write faults with `CR2` around `0xffff80c000000014`, which is + `P2V` of physical **768 GB**, far outside the 4 GB direct map `kvmalloc` + builds from four 1 GB pages. Then a double fault, then a triple fault and a + reboot loop. SeaBIOS assigns it low, so the BIOS path never sees it. + **Drop `-device virtio-gpu-pci` to boot UEFI past this.** +2. **Boot stalls after `cpu0: starting`**, before `schfs: mounted`. Under UEFI + the ESP is hd0 and schfs.img is hd1; the root never mounts. Not diagnosed. + +`cpu0: starting` remains the UEFI high-water mark, now reached with a truthful +memory map rather than a fabricated one. ## Testing