From 07c881cac7a5337f2bcc4ce4dcd373550dae3b35 Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 14 Oct 2026 19:15:31 +0200 Subject: [PATCH 1/6] Test oracles come from ACPI 6.5, the SDM and ToyOS's own reads; Linux is a goal in issues The follow-up the orchestrator ruled on #919 and #915: a reading captured under Linux is a black-box measurement for evidence and a goal in an issue, never a test oracle in the tree. - The turbostat fixtures (tests/metal/t14-linux/) leave the tree for the evidence repository. counters_on_metal no longer holds the spin to Linux's loaded clock: every CPU's APERF must run at least as fast as its MPERF across the spin, its busy clock at or above base frequency, since MPERF counts at close to the maximum non-turbo frequency and APERF at the actual one (SDM Vol. 3B 22.7.2). The idle and spinning figures are printed without a Linux column. - lib/acpi's thinkpad_t14.rs holds each expected value to the field ACPI 6.5 Tables 5.9, 5.10, 5.25 and 5.26 give the machine's bytes; the dangling fixtures/thinkpad-t14/SOURCE citation goes and the FADT test is renamed. resource.rs's list is held to 6.4.3.5.1's Resource Type rather than a journal's shape. acpi_events_on_metal cites those tables and the ECDT (5.2.15), as ToyOS's own boots read them. - acpi_death_on_metal holds the FACS lock word to 5.2.10: not in memory Table 15.6 maps to AddressRangeMemory (UEFI types 1, 2, 3, 4, 7), where it required type 10, which Linux printed. - the-tree-names-linux-as-an-authority.md: the exit's grep passes an interface named for Linux (Linux's `madvise`) and an issue slug. - The four security-track issues whose oracle was Linux's lines, reads or sequences take the vendor's guidance and ToyOS's own reads as their oracle; Linux's are a goal compared in evidence. - issues/README.md: a track lists its stages with the decisions its brief settled, replacing the rule that forbade a stage table. - Pointers at the removed directory and the turbostat floor follow. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016UzbDnM9m6nQWhbjGi6Lv1 --- issues/README.md | 13 +-- ...-the-vulnerabilities-lines-linux-prints.md | 21 +++-- ...the-bhb-fills-the-rsb-or-issues-an-ibpb.md | 7 +- ...ctrl-and-gds-stay-as-firmware-left-them.md | 9 +- ...are-measurements-or-make-several-claims.md | 2 +- .../the-tree-names-linux-as-an-authority.md | 13 ++- issues/the-tree-says-who-uses-each-thing.md | 7 +- issues/tsx-stays-as-firmware-left-it.md | 10 +-- lib/acpi/tests/resource.rs | 7 +- lib/acpi/tests/thinkpad_t14.rs | 22 ++--- tests/metal/t14-linux/SOURCE | 14 ---- tests/metal/t14-linux/turbostat-idle.txt | 60 -------------- tests/metal/t14-linux/turbostat-loaded.txt | 60 -------------- tests/toyos.rs | 83 ++++++++----------- 14 files changed, 97 insertions(+), 231 deletions(-) delete mode 100644 tests/metal/t14-linux/SOURCE delete mode 100644 tests/metal/t14-linux/turbostat-idle.txt delete mode 100644 tests/metal/t14-linux/turbostat-loaded.txt diff --git a/issues/README.md b/issues/README.md index 8f47354d636..7780b4ad778 100644 --- a/issues/README.md +++ b/issues/README.md @@ -62,12 +62,13 @@ and an agent that "fixes" one has decided something that was his to decide. But a file blocked on an *instrument* — a gate, a machine, a measurement — is not a question. Nobody has to decide it; somebody has to run it. -**`kind: track` is what a plan used to be**, and it is written to the length a -defect is. A `track` says what is to be built, what it is blocked on, and any -constraint a reader would otherwise pay to re-derive — a hardware bound, a -number somebody measured, a design line the owner already drew. It does not -carry a design, a stage table, a rationale or a review history: a design that is -right is written as code, and one that is not yet written is not yet known. +**`kind: track` is what a plan used to be.** A `track` says what is to be +built, what it is blocked on, and any constraint a reader would otherwise pay to +re-derive — a hardware bound, a number somebody measured, a design line the +owner already drew. Work that lands in stages lists them in order, each with +what it builds, the design decisions its brief settled and its exit. A track +carries no rationale and no review history: those stay in the pull requests and +commits that settled it. ## Slugs diff --git a/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md b/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md index 6e05ae1a3b5..2cdc02dbbfa 100644 --- a/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md +++ b/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md @@ -7,12 +7,15 @@ opened: 2026-09-29 # Each boot prints the vulnerabilities lines Linux prints **Exit**: each proving machine's ToyOS boot prints, for each vulnerabilities -file, the line Linux at `Ubuntu-6.8.0-142.142` printed on that machine: the -T14's from -`issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md`, -each EPYC guest's from its runner's capture. It omits only clauses about what -ToyOS does not run: `spectre_v1`'s swapgs barriers while it runs no `swapgs`, -the KVM and VM-exit clauses since it runs no guest, and `IBRS_FW` since the -kernel calls no firmware; `spec_store_bypass` reads "Mitigation: Speculative -Store Bypass disabled per program". **Mutation**: `ARCH_CAPABILITIES` read as -0 reds the T14. **Oracle**: Linux's lines. +file, a line stating what +`issues/a-pure-function-decides-a-cpus-speculation-mitigations-from-its-vendors-guidance.md` +decided for that CPU from the words ToyOS read there. It omits only clauses +about what ToyOS does not run: `spectre_v1`'s swapgs barriers while it runs no +`swapgs`, the KVM and VM-exit clauses since it runs no guest, and `IBRS_FW` +since the kernel calls no firmware; `spec_store_bypass` reads "Mitigation: +Speculative Store Bypass disabled per program". **Mutation**: +`ARCH_CAPABILITIES` read as 0 reds the T14. **Oracle**: the vendor's +guidance through that function, and ToyOS's own reads. The line Linux at +`Ubuntu-6.8.0-142.142` prints on each machine is the goal, compared in +evidence; a clause ToyOS's line lacks is a finding against this issue, never a +test's expected value. diff --git a/issues/no-entry-or-switch-clears-the-bhb-fills-the-rsb-or-issues-an-ibpb.md b/issues/no-entry-or-switch-clears-the-bhb-fills-the-rsb-or-issues-an-ibpb.md index e6be9a43d1d..3698896dce4 100644 --- a/issues/no-entry-or-switch-clears-the-bhb-fills-the-rsb-or-issues-an-ibpb.md +++ b/issues/no-entry-or-switch-clears-the-bhb-fills-the-rsb-or-issues-an-ibpb.md @@ -18,10 +18,13 @@ the ask is the flag of **Exit**: a gate over `kernel.elf`, on the decoder of `issues/no-gate-decodes-kernel-elfs-instructions.md`, matches it against -both of Linux's sequences; on +the branch history clearing and return stack filling sequences Intel's and +AMD's published guidance prescribes; on every proving machine probes count what `issues/a-pure-function-decides-a-cpus-speculation-mitigations-from-its-vendors-guidance.md` selects for it: a clear per syscall where it selects the loop, a fill per switch where it selects filling, and two IBPBs over B, C, idle, B, A, idle, A, B. **Mutation**: either sequence edited, the clear's condition inverted, no -fill, the IBPB decided by the previous root. **Oracle**: Linux's sequences. +fill, the IBPB decided by the previous root. **Oracle**: the vendors' +published sequences. Linux's sequences are a goal compared in evidence, never +the gate's expected text. diff --git a/issues/spec-ctrl-and-gds-stay-as-firmware-left-them.md b/issues/spec-ctrl-and-gds-stay-as-firmware-left-them.md index 5148631a608..e9a3a1c819a 100644 --- a/issues/spec-ctrl-and-gds-stay-as-firmware-left-them.md +++ b/issues/spec-ctrl-and-gds-stay-as-firmware-left-them.md @@ -15,7 +15,8 @@ unmitigated if firmware left `GDS_MITG_DIS` set. Linux at **Exit**: on every proving machine each CPU's 0x48 holds what `issues/a-pure-function-decides-a-cpus-speculation-mitigations-from-its-vendors-guidance.md` -selects for it, on the T14 Linux's read less SSBD; on the T14, the one proving -machine with GDS, a probe sets `GDS_MITG_DIS` and reads it clear after the -kernel's write. **Mutation**: the clear deleted. **Oracle**: Linux's reads on -each machine. +selects for it; on the T14, the one proving machine with GDS, a probe sets +`GDS_MITG_DIS` and reads it clear after the kernel's write. **Mutation**: the +clear deleted. **Oracle**: the vendor's guidance through that function, and +ToyOS's own reads on each machine. Linux's reads of 0x48 and 0x123 on each +machine are a goal compared in evidence, never a test's expected value. diff --git a/issues/suite-rows-that-are-measurements-or-make-several-claims.md b/issues/suite-rows-that-are-measurements-or-make-several-claims.md index 06deb2ca7a5..633cb37fdf5 100644 --- a/issues/suite-rows-that-are-measurements-or-make-several-claims.md +++ b/issues/suite-rows-that-are-measurements-or-make-several-claims.md @@ -20,7 +20,7 @@ Measurements as `METAL` rows in `tests/toyos.rs`: - `counters` (`counters_on_metal`): records fresh and named by APIC id, SMI counts moved only by the kernel's commands, MPERF against the stamp, an idle second with no log line, the HWP request - and a turbostat frequency floor. The HWP request's oracle is + and a base-frequency floor. The HWP request's oracle is `issues/t14-rows-hold-toyos-to-linuxs-choice-or-copy.md`'s. - `acpi_tables_loaded` (`acpi_tables_on_metal`): the definition-block count, the MTRRs compared across CPUs, nothing refused, and the AML reads. The count's oracle is the same issue's. diff --git a/issues/the-tree-names-linux-as-an-authority.md b/issues/the-tree-names-linux-as-an-authority.md index 582c621de60..df18ed6d6c6 100644 --- a/issues/the-tree-names-linux-as-an-authority.md +++ b/issues/the-tree-names-linux-as-an-authority.md @@ -31,6 +31,13 @@ the sweep's: `kernel/src/arch/aarch64/irqchip.rs`, Owner: the orchestrator, which has briefed the source sweep (`wt/toyos-linux-sweep`) to clear it. -**Exit**: `git grep -n -i linux -- kernel sdk/libc/src lib/acpi lib/hda lib/xhci lib/bcachefs -system/fileserver system/logkeeper system/netstack/i219 system/netstack/shard -system/netstack/node/tests tests/metal tests/toyos.rs tests/guest` prints nothing. +**Exit**: this prints nothing: + +``` +git grep -n -i -P "linux(?!'s \`madvise\`|s?-)" -- kernel sdk/libc/src lib/acpi lib/hda lib/xhci \ + lib/bcachefs system/fileserver system/logkeeper system/netstack/i219 system/netstack/shard \ + system/netstack/node/tests tests/metal tests/toyos.rs tests/guest +``` + +It passes an interface defined outside ToyOS that names Linux, which in these paths is only Linux's +`madvise`, and an issue slug, such as `issues/toyos-beats-linuxs-latency-on-the-t14.md`. diff --git a/issues/the-tree-says-who-uses-each-thing.md b/issues/the-tree-says-who-uses-each-thing.md index 7ceb9be2a47..6620d02cbb6 100644 --- a/issues/the-tree-says-who-uses-each-thing.md +++ b/issues/the-tree-says-who-uses-each-thing.md @@ -138,7 +138,7 @@ build/ CLAUDE.md; the root package's library and binaries (bin/ toyos-flash i ssh/ (package toyos-ssh) tests/ CLAUDE.md; toyos.rs checks.rs common/ checks/ (the root package's test targets) guest/ (proctest kernelprobe metalprobe test-runner rust-tests/) images/ (one .toml per boot case) - metal/ (package toyos-metal: the loop, and t14-linux/, the Linux readings) + metal/ (package toyos-metal: the loop) corpus/tinycc/ cavp/ ports/ /recipe.toml and patches/, empty until the first issues/ .md @@ -235,9 +235,8 @@ tree's top level: `.cargo`, `.claude`, `.github`, `.gitignore`, package depends on a path outside `sdk/`; `--build-only` and the guest suite green. 8. **Tests and images:** `images/`, `tests/images/`, `tests/metal/` (the - metal loop as package `toyos-metal`, with the Linux readings in - `t14-linux/`; a machine's records are in the host's store, so there is no - descriptor), `tests/guest/rust-tests/`, `tests/guest/c/` and + metal loop as package `toyos-metal`; a machine's records are in the + host's store, so there is no descriptor), `tests/guest/rust-tests/`, `tests/guest/c/` and `tests/corpus/tinycc/`. Image names stay `bootable-.img`. `whole_disk` and `Node`, which `toyos-flash` and the loop both read, are in `build/disk.rs`. Landed with stage 4, in one pull request. **Exit:** no diff --git a/issues/tsx-stays-as-firmware-left-it.md b/issues/tsx-stays-as-firmware-left-it.md index bfbdb5ed2fc..968b0b887ff 100644 --- a/issues/tsx-stays-as-firmware-left-it.md +++ b/issues/tsx-stays-as-firmware-left-it.md @@ -19,8 +19,8 @@ T14's `CONFIG_X86_INTEL_TSX_MODE_OFF=y`, runs `tsx_init` **Exit**: `issues/a-pure-function-decides-a-cpus-speculation-mitigations-from-its-vendors-guidance.md` -carries `tsx_init`'s decision and every CPU applies it; on the T14, ToyOS's -reads of 0x122, 0x10F and 0x123 equal the Linux reads of -`issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md` -where each exists, and dropping the write leaves 0x122 or 0x10F at firmware's -value and reds it. +carries the TSX decision of the vendor's guidance and every CPU applies it; on +the T14, ToyOS's own reads of 0x122, 0x10F and 0x123 hold what that decision +selects where each exists, and dropping the write leaves 0x122 or 0x10F at +firmware's value and reds it. Linux's reads of the same registers on the T14 +are a goal compared in evidence, never a test's expected value. diff --git a/lib/acpi/tests/resource.rs b/lib/acpi/tests/resource.rs index 5143196b739..ef121f11d95 100644 --- a/lib/acpi/tests/resource.rs +++ b/lib/acpi/tests/resource.rs @@ -27,9 +27,10 @@ fn windows(bytes: &[u8], room: usize) -> Result, ResourceE Ok(out) } -/// The shape the T14's firmware answers in, as Linux's own journal reports it: -/// two memory windows and the I/O and bus ranges beside them, of which only the -/// memory ones are windows a BAR could be placed in. +/// A root bridge's list carries bus number, I/O and memory ranges, which a +/// descriptor's Resource Type tells apart (ACPI 6.5 §6.4.3.5.1, byte 3: 0 +/// memory, 1 I/O, 2 bus number); only the memory ranges are windows a BAR +/// could be placed in. #[test] fn only_the_memory_ranges_of_a_root_bridge_become_windows() { let bytes = list(&[ diff --git a/lib/acpi/tests/thinkpad_t14.rs b/lib/acpi/tests/thinkpad_t14.rs index 3d4237a68ff..2414f78f05e 100644 --- a/lib/acpi/tests/thinkpad_t14.rs +++ b/lib/acpi/tests/thinkpad_t14.rs @@ -1,6 +1,5 @@ -//! The T14's fixed hardware and SCI, decoded from an -//! extract of its FACP and APIC and held against what Linux read on the -//! same machine (`fixtures/thinkpad-t14/SOURCE`). +//! The T14's fixed hardware and SCI, decoded from an extract of its FACP and +//! APIC and held to what ACPI 6.5 says the machine's bytes mean. //! //! **An extract, never the tables**: each table here is laid out from the //! fields `fixed_hardware`, `pm1a_control` and `sci_line` read, at their offsets and @@ -65,14 +64,13 @@ fn open(bytes: Vec, signature: &[u8; 4], needed: usize) -> Table = APIC_OVERRIDES.iter().flat_map(|o| entry(o[0], o[1], &o[2..])).collect(); diff --git a/tests/metal/t14-linux/SOURCE b/tests/metal/t14-linux/SOURCE deleted file mode 100644 index d59763d1e66..00000000000 --- a/tests/metal/t14-linux/SOURCE +++ /dev/null @@ -1,14 +0,0 @@ -Linux's turbostat on the ThinkPad T14 the metal suite runs on, under that -machine's Ubuntu (`6.8.0-142-generic`, the `powersave` governor), taken as -root by the orchestrator on 2026-10-03, one after the other, each as the tool -printed it; `counters_on_metal` in `tests/toyos.rs` prints ToyOS's reading -beside them. - - turbostat-idle.txt 60 s of an idle machine: - `turbostat --quiet --interval 10 --num_iterations 6 --show - Core,CPU,Avg_MHz,Busy%,Bzy_MHz,TSC_MHz,IRQ,SMI,CPU%c1,CPU%c6,CPU%c7,CoreTmp,PkgTmp,Pkg%pc2,Pkg%pc3,Pkg%pc6,Pkg%pc7,Pkg%pc8,Pkg%pc9,Pk%pc10,PkgWatt,CorWatt` - turbostat-loaded.txt 60 s with one `yes` per CPU, started 2 s before: - `for i in 1 2 3 4 5 6 7 8; do timeout 65 sh -c "yes > /dev/null" & done; - sleep 2; turbostat --quiet --interval 10 --num_iterations 6 --show - Core,CPU,Avg_MHz,Busy%,Bzy_MHz,TSC_MHz,IRQ,SMI,CPU%c1,CPU%c6,CPU%c7,CoreTmp,PkgTmp,Pkg%pc2,Pkg%pc6,Pk%pc10,PkgWatt,CorWatt; - wait` diff --git a/tests/metal/t14-linux/turbostat-idle.txt b/tests/metal/t14-linux/turbostat-idle.txt deleted file mode 100644 index 298df608572..00000000000 --- a/tests/metal/t14-linux/turbostat-idle.txt +++ /dev/null @@ -1,60 +0,0 @@ -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 Pkg%pc8 Pkg%pc9 Pk%pc10 PkgWatt CorWatt -- - 1 0.11 994 2419 1160 0 0.47 0.00 99.98 29 31 17.46 2.01 0.03 0.29 77.22 0.00 0.00 1.30 0.07 -0 0 1 0.11 1012 2419 131 0 0.12 0.00 100.42 26 31 17.46 2.01 0.03 0.29 77.22 0.00 0.00 1.30 0.07 -0 4 0 0.05 910 2419 53 0 0.12 -1 1 1 0.08 986 2419 57 0 0.30 0.00 100.18 27 -1 5 1 0.12 999 2419 119 0 0.30 -2 2 1 0.13 933 2419 423 0 1.29 0.00 99.04 29 -2 6 2 0.19 1002 2419 157 0 1.29 -3 3 1 0.14 978 2419 148 0 0.16 0.00 100.27 28 -3 7 1 0.09 1115 2419 72 0 0.16 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 Pkg%pc8 Pkg%pc9 Pk%pc10 PkgWatt CorWatt -- - 1 0.11 980 2419 1009 0 0.38 0.00 100.08 29 30 19.01 1.80 0.05 0.22 76.10 0.00 0.00 1.81 0.07 -0 0 1 0.07 975 2419 46 0 0.14 0.00 100.37 26 30 19.01 1.80 0.05 0.22 76.10 0.00 0.00 1.81 0.07 -0 4 1 0.11 913 2419 72 0 0.14 -1 1 0 0.03 997 2419 23 0 0.19 0.00 100.34 25 -1 5 1 0.13 993 2419 130 0 0.19 -2 2 1 0.11 943 2419 386 0 1.14 0.00 99.27 29 -2 6 2 0.18 1035 2419 155 0 1.14 -3 3 1 0.14 967 2419 141 0 0.06 0.00 100.36 27 -3 7 1 0.09 997 2419 56 0 0.06 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 Pkg%pc8 Pkg%pc9 Pk%pc10 PkgWatt CorWatt -- - 1 0.11 1005 2419 1125 0 0.42 0.00 100.03 29 31 19.47 1.35 0.06 0.23 75.87 0.00 0.00 1.43 0.07 -0 0 1 0.12 1081 2419 42 0 0.08 0.00 100.39 26 31 19.47 1.35 0.06 0.23 75.87 0.00 0.00 1.43 0.07 -0 4 1 0.13 998 2419 56 0 0.08 -1 1 1 0.10 1006 2419 127 0 0.22 0.00 100.21 25 -1 5 1 0.14 1004 2419 132 0 0.22 -2 2 2 0.16 981 2419 513 0 1.33 0.00 99.12 29 -2 6 1 0.08 1028 2419 75 0 1.33 -3 3 1 0.13 953 2419 137 0 0.05 0.00 100.42 28 -3 7 1 0.06 1019 2419 43 0 0.05 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 Pkg%pc8 Pkg%pc9 Pk%pc10 PkgWatt CorWatt -- - 6 0.36 1668 2419 1966 0 1.14 0.00 98.78 29 32 18.49 1.12 0.04 0.33 75.47 0.00 0.00 1.14 0.13 -0 0 7 0.43 1587 2419 231 0 0.90 0.00 99.10 26 32 18.49 1.12 0.04 0.33 75.47 0.00 0.00 1.14 0.13 -0 4 2 0.15 994 2419 96 0 0.90 -1 1 11 0.48 2410 2419 185 0 1.08 0.00 98.67 27 -1 5 7 0.46 1450 2419 348 0 1.08 -2 2 8 0.48 1564 2419 635 0 1.97 0.00 98.11 29 -2 6 1 0.08 1040 2419 72 0 1.97 -3 3 12 0.69 1725 2419 326 0 0.60 0.00 99.24 28 -3 7 1 0.08 1053 2419 73 0 0.60 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 Pkg%pc8 Pkg%pc9 Pk%pc10 PkgWatt CorWatt -- - 1 0.12 984 2419 1166 0 0.39 0.00 100.01 29 31 13.62 2.79 0.04 0.39 80.55 0.00 0.00 1.30 0.07 -0 0 0 0.05 957 2419 34 0 0.09 0.00 100.41 26 31 13.62 2.79 0.04 0.39 80.55 0.00 0.00 1.30 0.07 -0 4 1 0.13 943 2419 78 0 0.09 -1 1 1 0.05 982 2419 47 0 0.36 0.00 100.00 27 -1 5 2 0.23 1023 2419 186 0 0.36 -2 2 1 0.05 1001 2419 45 0 0.09 0.00 100.38 29 -2 6 2 0.15 989 2419 135 0 0.09 -3 3 2 0.22 959 2419 535 0 1.04 0.00 99.26 28 -3 7 1 0.10 994 2419 106 0 1.04 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 Pkg%pc8 Pkg%pc9 Pk%pc10 PkgWatt CorWatt -- - 1 0.12 980 2419 1156 0 0.39 0.00 100.03 28 31 13.35 1.53 0.07 0.41 82.10 0.00 0.00 1.88 0.07 -0 0 1 0.05 958 2419 40 0 0.16 0.00 100.38 26 31 13.35 1.53 0.07 0.41 82.10 0.00 0.00 1.88 0.07 -0 4 1 0.11 947 2419 82 0 0.16 -1 1 1 0.09 989 2419 76 0 0.26 0.00 100.09 26 -1 5 2 0.19 990 2419 174 0 0.26 -2 2 1 0.09 965 2419 335 0 0.96 0.00 99.42 28 -2 6 2 0.19 995 2419 178 0 0.96 -3 3 2 0.19 976 2419 242 0 0.18 0.00 100.24 28 -3 7 0 0.04 1021 2419 29 0 0.18 diff --git a/tests/metal/t14-linux/turbostat-loaded.txt b/tests/metal/t14-linux/turbostat-loaded.txt deleted file mode 100644 index df181dbeeb5..00000000000 --- a/tests/metal/t14-linux/turbostat-loaded.txt +++ /dev/null @@ -1,60 +0,0 @@ -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc6 Pk%pc10 PkgWatt CorWatt -- - 3791 99.77 3800 2419 80691 0 0.00 0.00 0.00 71 71 0.00 0.00 0.00 30.24 27.88 -0 0 3791 99.77 3800 2419 10023 0 0.00 0.00 0.00 61 71 0.00 0.00 0.00 30.24 27.88 -0 4 3791 99.77 3800 2419 10021 0 0.00 -1 1 3791 99.77 3800 2419 10066 0 0.00 0.00 0.00 71 -1 5 3791 99.77 3800 2419 10102 0 0.00 -2 2 3791 99.77 3800 2419 10031 0 0.00 0.00 0.00 62 -2 6 3791 99.77 3800 2419 10274 0 0.00 -3 3 3791 99.77 3800 2419 10125 0 0.00 0.00 0.00 71 -3 7 3791 99.77 3800 2419 10049 0 0.00 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc6 Pk%pc10 PkgWatt CorWatt -- - 3791 99.77 3800 2419 80659 0 0.00 0.00 0.00 79 79 0.00 0.00 0.00 30.73 28.29 -0 0 3791 99.77 3800 2419 10012 0 0.00 0.00 0.00 68 79 0.00 0.00 0.00 30.73 28.29 -0 4 3791 99.77 3800 2419 10014 0 0.00 -1 1 3791 99.77 3800 2419 10026 0 0.00 0.00 0.00 79 -1 5 3791 99.77 3800 2419 10095 0 0.00 -2 2 3791 99.77 3800 2419 10017 0 0.00 0.00 0.00 69 -2 6 3791 99.77 3800 2419 10364 0 0.00 -3 3 3791 99.77 3800 2419 10122 0 0.00 0.00 0.00 78 -3 7 3791 99.77 3800 2419 10009 0 0.00 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc6 Pk%pc10 PkgWatt CorWatt -- - 3547 99.77 3555 2419 80555 0 0.00 0.00 0.00 66 66 0.00 0.00 0.00 27.20 24.72 -0 0 3547 99.77 3555 2419 10021 0 0.00 0.00 0.00 58 66 0.00 0.00 0.00 27.20 24.72 -0 4 3547 99.77 3555 2419 10010 0 0.00 -1 1 3547 99.77 3555 2419 10028 0 0.00 0.00 0.00 65 -1 5 3547 99.77 3555 2419 10037 0 0.00 -2 2 3547 99.77 3555 2419 10028 0 0.00 0.00 0.00 60 -2 6 3547 99.77 3555 2419 10246 0 0.00 -3 3 3547 99.77 3555 2419 10173 0 0.00 0.00 0.00 66 -3 7 3547 99.77 3555 2419 10012 0 0.00 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc6 Pk%pc10 PkgWatt CorWatt -- - 3068 99.77 3075 2419 80909 0 0.00 0.00 0.00 65 65 0.00 0.00 0.00 19.62 17.18 -0 0 3068 99.77 3075 2419 10054 0 0.00 0.00 0.00 59 65 0.00 0.00 0.00 19.62 17.18 -0 4 3068 99.77 3075 2419 10029 0 0.00 -1 1 3068 99.77 3075 2419 10121 0 0.00 0.00 0.00 65 -1 5 3068 99.77 3075 2419 10039 0 0.00 -2 2 3068 99.77 3075 2419 10069 0 0.00 0.00 0.00 59 -2 6 3068 99.77 3075 2419 10276 0 0.00 -3 3 3068 99.77 3075 2419 10229 0 0.00 0.00 0.00 64 -3 7 3068 99.76 3075 2419 10092 0 0.00 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc6 Pk%pc10 PkgWatt CorWatt -- - 3083 99.77 3090 2419 80593 0 0.00 0.00 0.00 65 65 0.00 0.00 0.00 19.85 17.43 -0 0 3083 99.77 3090 2419 10008 0 0.00 0.00 0.00 58 65 0.00 0.00 0.00 19.85 17.43 -0 4 3083 99.77 3090 2419 10020 0 0.00 -1 1 3083 99.77 3090 2419 10006 0 0.00 0.00 0.00 64 -1 5 3083 99.77 3090 2419 10019 0 0.00 -2 2 3083 99.77 3090 2419 10028 0 0.00 0.00 0.00 60 -2 6 3083 99.77 3090 2419 10282 0 0.00 -3 3 3083 99.77 3090 2419 10221 0 0.00 0.00 0.00 65 -3 7 3083 99.77 3090 2419 10009 0 0.00 -Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz IRQ SMI CPU%c1 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc6 Pk%pc10 PkgWatt CorWatt -- - 3087 99.77 3094 2419 80544 0 0.00 0.00 0.00 65 65 0.00 0.00 0.00 19.92 17.49 -0 0 3087 99.77 3094 2419 10009 0 0.00 0.00 0.00 58 65 0.00 0.00 0.00 19.92 17.49 -0 4 3087 99.77 3094 2419 10011 0 0.00 -1 1 3087 99.77 3094 2419 10012 0 0.00 0.00 0.00 65 -1 5 3087 99.77 3094 2419 10009 0 0.00 -2 2 3087 99.77 3094 2419 10017 0 0.00 0.00 0.00 59 -2 6 3087 99.77 3094 2419 10273 0 0.00 -3 3 3087 99.77 3094 2419 10205 0 0.00 0.00 0.00 65 -3 7 3087 99.77 3094 2419 10008 0 0.00 diff --git a/tests/toyos.rs b/tests/toyos.rs index 86f930e33cd..ed161984fb2 100644 --- a/tests/toyos.rs +++ b/tests/toyos.rs @@ -578,7 +578,7 @@ const METAL: &[(&str, metal::Metal)] = &[ ( // Every CPU's counters as the shipped syscall reads them, across an // idle second and a spin on every CPU: `counters_on_metal` says what - // is held and what is read beside Linux's. + // is held and what is only read. "counters", metal::Metal { arms: &[metal::once("testcases", "tests/images/testcases.toml", &[], &["test_rs_counters_metal"])], @@ -5009,15 +5009,17 @@ const SMI_SPAN_NS: u64 = 4_444_000_000; /// nothing else: every firmware interrupt is one ToyOS asked for. Across the spin every /// CPU's MPERF ran nine tenths of its stamp or more [e], a CPU in C0 the whole /// span: MPERF counts at the TSC's rate there (SDM Vol. 3B, "Hardware -/// Coordination Feedback"); and every CPU's busy frequency reached the lowest -/// Linux's turbostat read under one `yes` per CPU on the same machine over the -/// same span of load (`tests/metal/t14-linux/turbostat-loaded.txt`). +/// Coordination Feedback"); and every CPU's APERF ran at least as fast as its +/// MPERF across the spin, its busy clock at or above its base frequency: MPERF +/// counts at close to the maximum non-turbo frequency and APERF at the actual +/// one (SDM Vol. 3B §22.7.2), so a spinning CPU below it is held there by its +/// request, a power limit or firmware. /// -/// Read and not held, beside Linux's turbostat: each CPU's idle busy -/// fraction, which an SMI in the idle second raises on every CPU alike by the -/// time it held them, and what one round cost its reader; and beside Linux's loaded -/// timer reading (`issues/toyos-beats-linuxs-latency-on-the-t14.md`), -/// how late each CPU's kick handler ran under the `loaded` phase. +/// Read and not held: each CPU's idle busy fraction, which an SMI in the idle +/// second raises on every CPU alike by the time it held them, its spinning +/// clock, what one round cost its reader, and how late each CPU's kick handler +/// ran under the `loaded` phase, which +/// `issues/toyos-beats-linuxs-latency-on-the-t14.md` sets its bar for. fn counters_on_metal(back: &metal::Readback) -> Result<(), String> { type Read<'a> = BTreeMap>; back.job_passed("test_rs_counters_metal")?; @@ -5148,60 +5150,36 @@ fn counters_on_metal(back: &metal::Readback) -> Result<(), String> { if busy.iter().any(|&b| b < 0.9) { return Err(format!("MPERF ran {busy:?} of each stamp across the spin, some cpu under 0.9")); } - // Each interval's machine-wide row, in order. - let linux = |file: &str, column: &str| -> Result, String> { - let mut rows = file.lines().map(|l| l.split('\t').collect::>()); - let header = rows.next().ok_or("an empty turbostat reading")?; - let at = header.iter().position(|c| *c == column).ok_or_else(|| format!("turbostat read no {column}"))?; - Ok(rows.filter(|r| r[0] == "-").filter_map(|r| r.get(at)?.parse().ok()).collect()) - }; log.must_say("counters_metal loaded: ")?; for said in log.text().lines().filter(|l| l.contains("counters_metal loaded: ")) { eprintln!(" [counters] {}", said.split("counters_metal ").nth(1).unwrap_or(said).trim()); } - let range = |values: &[f64]| values.iter().fold((f64::MAX, f64::MIN), |(lo, hi), &v| (lo.min(v), hi.max(v))); - let idle = range(&linux(include_str!("metal/t14-linux/turbostat-idle.txt"), "Busy%")?); - let loaded_rows = linux(include_str!("metal/t14-linux/turbostat-loaded.txt"), "Bzy_MHz")?; - let loaded = range(&loaded_rows); - // The floor is Linux's clock over the spin's own span of load, not after - // the package settles: the intervals that open within it, the first 2 s - // into Linux's load and each 10 s long (`tests/metal/t14-linux/SOURCE`). - let spin_ns = at2 - at1; - let opened = loaded_rows.iter().enumerate().take_while(|&(k, _)| 2_000_000_000 + k as u64 * 10_000_000_000 < spin_ns); - let floor = opened.map(|(_, &mhz)| mhz).fold(f64::MAX, f64::min); - if floor == f64::MAX { - return Err(format!("the spin lasted {spin_ns} ns, and no Linux interval opens within it")); - } - let spinning: Vec = (0..cpus).map(|cpu| tsc_mhz * ratio(idle1, spin, cpu, "aperf", "mperf")).collect(); + let above_base: Vec = (0..cpus).map(|cpu| ratio(idle1, spin, cpu, "aperf", "mperf")).collect(); eprintln!( " [counters] {cpus} cpus, the SMI count on each moved by {asked} over {} ms, the commands the kernel wrote to SMI_CMD in it; TSC {tsc_mhz:.0} MHz", (at2 - at0) / 1_000_000 ); for (cpu, busy) in busy.iter().enumerate() { eprintln!( - " [counters] cpu{cpu}: idle busy {:.2}% (Linux {:.2}-{:.2}%), spinning {:.0} MHz (Linux {floor:.0} over \ - this span, {:.0}-{:.0} loaded), busy {busy:.3}", + " [counters] cpu{cpu}: idle busy {:.2}%, spinning {:.0} MHz, busy {busy:.3}", ratio(idle0, idle1, cpu, "mperf", "stamp") * 100.0, - idle.0, - idle.1, - spinning[cpu], - loaded.0, - loaded.1, + tsc_mhz * above_base[cpu], ); } eprintln!(" [counters] the spin's read, a whole round, took its reader {} ns", clock["spin"].1); - if spinning.iter().any(|&mhz| mhz < floor) { - return Err(format!("spinning {spin_ns} ns at {spinning:.0?} MHz, some cpu below the {floor:.0} Linux held over that span")); + if above_base.iter().any(|&r| r < 1.0) { + return Err(format!("APERF ran {above_base:.3?} of MPERF across the spin, some cpu below its base frequency")); } Ok(()) } /// The T14's ACPI row as the kernel filled it from the machine's FACP and -/// APIC (Linux on the same machine: `INT_SRC_OVR (bus 0 bus_irq 9 global_irq -/// 9 high level)`), the server armed on it, the embedded controller it found -/// in the DSDT the one Linux used (`EC_CMD/EC_SC=0x66, EC_DATA=0x62`, -/// `GPE=0x6e`), at least one of its queries taken and a count of them -/// logged, and no guard of the server's fired. +/// APIC, each value the field ACPI 6.5 Tables 5.9, 5.10, 5.25 and 5.26 give +/// the machine's bytes (`lib/acpi/tests/thinkpad_t14.rs`); the server armed on +/// it; the embedded controller at the ports and GPE the T14's ECDT names (ACPI +/// 6.5 §5.2.15), as ToyOS's own boots there read it; at least one of its +/// queries taken and a count of them logged, and no guard of the server's +/// fired. fn acpi_events_on_metal(back: &metal::Readback) -> Result<(), String> { back.job_passed("test_rs_acpi_counted")?; back.job_passed("test_rs_acpi_hold")?; @@ -5507,15 +5485,19 @@ fn battery_on_metal(back: &metal::Readback) -> Result<(), String> { /// enable was asked from another CPU: the job claims from a thread it found /// off the boot processor, so that write is the one that crossed. And the /// Global Lock this machine's firmware keeps: the kernel read the FACS its -/// FADT names through the direct map and found the lock word in ACPI NVS -/// memory (type 10) by the firmware's own map, which is where Linux's print -/// of the same map puts it. +/// FADT names through the direct map and found the lock word in memory the +/// firmware's own map does not report as `AddressRangeMemory`, which ACPI 6.5 +/// §5.2.10 forbids the FACS. fn acpi_death_on_metal(back: &metal::Readback) -> Result<(), String> { back.job_passed("test_rs_acpi_release")?; let kernel = back.kernel(); let lock = kernel.must_say("acpi: the Global Lock is the FACS's at ")?.trim(); - if !lock.ends_with(", in memory the firmware's map types 10") { - return Err(format!("the Global Lock's word is not in ACPI NVS memory: {lock}")); + let uefi_type = lock + .rsplit_once(", in memory the firmware's map types ") + .and_then(|(_, ty)| ty.parse::().ok()) + .ok_or_else(|| format!("the Global Lock's line names no memory type: {lock}"))?; + if ADDRESS_RANGE_MEMORY.contains(&uefi_type) { + return Err(format!("the Global Lock's word is in AddressRangeMemory: {lock}")); } eprintln!(" [acpi] {lock}"); let enabled = kernel.must_say("acpi: ACPI mode: ACPI_ENABLE 0xf0 written to SMI_CMD 0xb2 ")?; @@ -5531,6 +5513,9 @@ fn acpi_death_on_metal(back: &metal::Readback) -> Result<(), String> { Ok(()) } +/// The UEFI memory types ACPI 6.5 Table 15.6 maps to `AddressRangeMemory`. +const ADDRESS_RANGE_MEMORY: [u8; 5] = [1, 2, 3, 4, 7]; + /// The CPU a kernel line says wrote `SMI_CMD`, read on that CPU beside the /// `out`: the boot processor, cpu0, or the line is refused (ACPI 6.5 Table /// 5.9, "from the boot processor"). From 446b912bde99345bff3c4e5418fdaff4df4f37f8 Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 14 Oct 2026 19:17:54 +0200 Subject: [PATCH 2/6] The T14's turbostat readings are a measurement in evidence, not an oracle They moved to ToyOSOrg/evidence pr-929/t14-linux at 423044d28 with their provenance. The readings issue records them as a measurement and its exit names what is still owed before the wipe: the Linux counter readings issues/toyos-explains-itself.md asks for. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016UzbDnM9m6nQWhbjGi6Lv1 --- ...-model-lack-reads-owed-before-the-t14s-wipe.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md b/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md index 4b6ad61c4fe..0cde1ad5297 100644 --- a/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md +++ b/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md @@ -13,17 +13,18 @@ Ubuntu leaves the T14 only after this issue and `issues/no-program-measures-toyos-against-linux-on-one-machine.md` close. -**Exit**: `wt/toyos-linux-sweep`, which holds this section and this slug -under #915's fence, settles the turbostat readings below. +**Exit**: every reading another issue owes of Linux on the T14 before its +wipe is taken and published in evidence; today that is +`issues/toyos-explains-itself.md`'s Linux reading of each counter ToyOS reads +there. ## Linux's counter readings, read 2026-10-03 -The orchestrator takes this Linux as the one independent oracle for the T14's -hardware counters (`issues/toyos-explains-itself.md`). Read as +A measurement of Linux on the same machine, never a test's oracle. Read as root under Ubuntu's `6.8.0-142-generic` from 16:22:37 UTC, one after the -other, and committed whole with their commands in the `SOURCE` beside them: -turbostat idle and under one `yes` per CPU in `tests/metal/t14-linux/`, which -`counters_on_metal` prints ToyOS's reading beside. +other, and published whole with their commands in +[evidence](https://github.com/ToyOSOrg/evidence/tree/423044d281a0e0df5bde10688b2baf59ca2be9b6/pr-929/t14-linux): +turbostat idle and under one `yes` per CPU. Idle, per 10 s: busy 0.11 to 0.36%, busy clock 980 to 1668 MHz, TSC 2419 MHz, SMI 0. Loaded: busy 99.77%, busy clock 3800 MHz for the first two intervals, 3555 MHz in the third, then 3075 to 3094 MHz; SMI 0. From f8acc182da61deeb4a1318e36e81d76dbbd5276b Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 14 Oct 2026 19:46:33 +0200 Subject: [PATCH 3/6] The tree names Linux as an authority no more: its issue closes; explains-itself's counters take the SDM's bound issues/the-tree-names-linux-as-an-authority.md is met and deleted. Its exit grep, at the parent of this commit, prints nothing (git grep exit 1): git grep -n -i -P "linux(?!'s `madvise`|s?-)" -- kernel sdk/libc/src \ lib/acpi lib/hda lib/xhci lib/bcachefs system/fileserver \ system/logkeeper system/netstack/i219 system/netstack/shard \ system/netstack/node/tests tests/metal tests/toyos.rs tests/guest No file outside it cites its slug or path. Its rule already lives in root CLAUDE.md's Research and dependencies and reviewer.md's Tests and operational checks, so nothing is folded. issues/toyos-explains-itself.md's exit held each T14 counter against Linux's reading; under the owner's 2026-10-13 rule a row holds it to the SDM's bound, as counters_on_metal holds the busy clock to base frequency, and Linux's reading is a goal compared in evidence. The readings issue's exit no longer names that reading as owed to a row. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016UzbDnM9m6nQWhbjGi6Lv1 --- ...el-lack-reads-owed-before-the-t14s-wipe.md | 4 +- .../the-tree-names-linux-as-an-authority.md | 43 ------------------- issues/toyos-explains-itself.md | 7 ++- 3 files changed, 6 insertions(+), 48 deletions(-) delete mode 100644 issues/the-tree-names-linux-as-an-authority.md diff --git a/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md b/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md index 0cde1ad5297..93d10453ca9 100644 --- a/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md +++ b/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md @@ -14,9 +14,7 @@ Ubuntu leaves the T14 only after this issue and close. **Exit**: every reading another issue owes of Linux on the T14 before its -wipe is taken and published in evidence; today that is -`issues/toyos-explains-itself.md`'s Linux reading of each counter ToyOS reads -there. +wipe is taken and published in evidence. ## Linux's counter readings, read 2026-10-03 diff --git a/issues/the-tree-names-linux-as-an-authority.md b/issues/the-tree-names-linux-as-an-authority.md deleted file mode 100644 index df18ed6d6c6..00000000000 --- a/issues/the-tree-names-linux-as-an-authority.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -status: assigned -kind: defect -opened: 2026-10-12 ---- - -# The tree names Linux as an authority - -Root `CLAUDE.md`'s Zero legacy, `implementer.md`'s Measure, build, test and `reviewer.md`'s **Fit** -and **Tests** (#902): source, tests and manifests name Linux only as a host platform, or the name of -an interface defined outside ToyOS (a `libc` item, a firmware's `_OSI` string, a partition type), -nothing takes its authority from another implementation's source, and a test's oracle for what -hardware does is the vendor's document or ToyOS's own read checked against it, never a reading -captured under Linux. The tree breaks all three: a design cites Linux's source (`kernel/src/mm/mmio.rs`, `system/netstack/shard/tcp/src/rx.rs`), a value is set as Linux's -(`system/fileserver/src/resolve.rs`, `kernel/src/arch/x86_64/vtd/queue.rs`, -`sdk/libc/src/linkreq.rs`, `sdk/libc/src/sockopt.rs`, `sdk/libc/src/memreq.rs`, -`sdk/libc/src/posix_io.rs`, `sdk/libc/src/sigmask.rs`), and tests hold -ToyOS to Linux's code or readings (`system/netstack/i219/src/tests.rs`, -`lib/acpi/tests/thinkpad_t14.rs`, the T14 rows in `tests/toyos.rs` reading -`tests/metal/t14-linux/`). - -Evidence: every mention outside `issues/` at `07b5879ee`, -[linux-mentions.txt](https://github.com/ToyOSOrg/evidence/blob/f42f8ab5a1107210c8e487963d9c530eb67741f4/linux-mentions.txt). - -`kernel/cpuvuln` and its fixtures went in #915. The other kernel lines are -the sweep's: `kernel/src/arch/aarch64/irqchip.rs`, -`kernel/src/arch/x86_64/vtd/fault.rs`, -`kernel/src/arch/x86_64/vtd/queue.rs`, `kernel/src/mm/mmio.rs` and -`kernel/usbhid`. - -Owner: the orchestrator, which has briefed the source sweep -(`wt/toyos-linux-sweep`) to clear it. - -**Exit**: this prints nothing: - -``` -git grep -n -i -P "linux(?!'s \`madvise\`|s?-)" -- kernel sdk/libc/src lib/acpi lib/hda lib/xhci \ - lib/bcachefs system/fileserver system/logkeeper system/netstack/i219 system/netstack/shard \ - system/netstack/node/tests tests/metal tests/toyos.rs tests/guest -``` - -It passes an interface defined outside ToyOS that names Linux, which in these paths is only Linux's -`madvise`, and an issue slug, such as `issues/toyos-beats-linuxs-latency-on-the-t14.md`. diff --git a/issues/toyos-explains-itself.md b/issues/toyos-explains-itself.md index b5bc757632e..447a0208cff 100644 --- a/issues/toyos-explains-itself.md +++ b/issues/toyos-explains-itself.md @@ -79,5 +79,8 @@ thermal counters, the log's steps, accounting, `inspect` and `size`. manifest row names; a program without the counters right is refused a counter read, and one that holds it but not `trace` is refused the power and per-device interrupt counters; and a T14 row holds each counter ToyOS reads -there against Linux's reading of it -(`issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md`). +there to the bound Intel's SDM gives it, as `counters_on_metal` holds the busy +clock to base frequency. Linux's reading of each counter is a goal compared in +evidence +(`issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md`), +never a row's expected value. From 51414738d2572ebaeaa2df73ebe6e8b234645859 Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 14 Oct 2026 20:08:01 +0200 Subject: [PATCH 4/6] Review round 1: the counters row says it holds the busy clock to MPERF's rate; the issues' oracles hold - counters_on_metal: APERF/MPERF >= 1 holds each spinning CPU's busy clock at or above the rate MPERF counts at, the TSC's (2419.2 MHz on the T14), not base frequency (Intel's 2400 MHz for that part). One SDM citation, revision pinned; the ratio is named aperf_per_mperf and the refusal says what it refused. - each-boot-prints-the-vulnerabilities-lines-linux-prints.md: the T14's logged words must equal the words the pure-function issue commits with provenance, so ARCH_CAPABILITIES read as 0 reds again. - toyos-explains-itself.md: the SDM's bound "where it gives one". - The readings issue's exit names the two issues whose Linux readings it owes. - no-program-measures-toyos-against-linux-on-one-machine.md: the outputs go to evidence and Linux's are a goal, never a fixture oracle. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016UzbDnM9m6nQWhbjGi6Lv1 --- ...-the-vulnerabilities-lines-linux-prints.md | 6 ++++-- ...el-lack-reads-owed-before-the-t14s-wipe.md | 7 +++++-- ...ures-toyos-against-linux-on-one-machine.md | 10 ++++++---- issues/toyos-explains-itself.md | 2 +- tests/toyos.rs | 20 +++++++++---------- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md b/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md index 2cdc02dbbfa..158f090784b 100644 --- a/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md +++ b/issues/each-boot-prints-the-vulnerabilities-lines-linux-prints.md @@ -9,13 +9,15 @@ opened: 2026-09-29 **Exit**: each proving machine's ToyOS boot prints, for each vulnerabilities file, a line stating what `issues/a-pure-function-decides-a-cpus-speculation-mitigations-from-its-vendors-guidance.md` -decided for that CPU from the words ToyOS read there. It omits only clauses +decided for that CPU from the words ToyOS read there, and on the T14 the words +it logs equal the T14's words that issue commits with their provenance, so its +line is the function's verdict on them. It omits only clauses about what ToyOS does not run: `spectre_v1`'s swapgs barriers while it runs no `swapgs`, the KVM and VM-exit clauses since it runs no guest, and `IBRS_FW` since the kernel calls no firmware; `spec_store_bypass` reads "Mitigation: Speculative Store Bypass disabled per program". **Mutation**: `ARCH_CAPABILITIES` read as 0 reds the T14. **Oracle**: the vendor's -guidance through that function, and ToyOS's own reads. The line Linux at +guidance through that function, over the words committed with provenance. The line Linux at `Ubuntu-6.8.0-142.142` prints on each machine is the goal, compared in evidence; a clause ToyOS's line lacks is a finding against this issue, never a test's expected value. diff --git a/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md b/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md index 93d10453ca9..81fce5ed6a7 100644 --- a/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md +++ b/issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md @@ -13,8 +13,11 @@ Ubuntu leaves the T14 only after this issue and `issues/no-program-measures-toyos-against-linux-on-one-machine.md` close. -**Exit**: every reading another issue owes of Linux on the T14 before its -wipe is taken and published in evidence. +**Exit**: the Linux readings on the T14 that +`issues/toyos-explains-itself.md` (each counter ToyOS reads there) and +`issues/no-program-measures-toyos-against-linux-on-one-machine.md` (that +program's outputs under Ubuntu) compare against are taken before the wipe and +published in evidence. ## Linux's counter readings, read 2026-10-03 diff --git a/issues/no-program-measures-toyos-against-linux-on-one-machine.md b/issues/no-program-measures-toyos-against-linux-on-one-machine.md index d038a36cf7b..47a38a7bcb8 100644 --- a/issues/no-program-measures-toyos-against-linux-on-one-machine.md +++ b/issues/no-program-measures-toyos-against-linux-on-one-machine.md @@ -17,10 +17,12 @@ sides each read their x2APIC ID from CPUID.0BH:EDX before and after the timed window, and a pure function over the four readings refuses the figure when the two sides' IDs match or either side's changed across the window. -**Exit**: the outputs committed as fixtures, and that function host-tested. -**Mutation**, each red: a pair on one CPU passes; only the readings before the -window compared, so a sibling that moved onto the initiator's CPU inside it -passes. **Oracle**: Linux. +**Exit**: both runs' outputs published in evidence, and that function +host-tested on crafted readings. **Mutation**, each red: a pair on one CPU +passes; only the readings before the window compared, so a sibling that moved +onto the initiator's CPU inside it passes. **Oracle**: the function's rule over +the x2APIC IDs it is handed. Linux's outputs are a goal ToyOS's are compared +against in evidence, never a fixture a test reads. What stands nearest is `counters_metal`'s `loaded` phase (`tests/guest/rust-tests/src/bin/counters_metal.rs`), the one lateness reading diff --git a/issues/toyos-explains-itself.md b/issues/toyos-explains-itself.md index 447a0208cff..1f5589d222c 100644 --- a/issues/toyos-explains-itself.md +++ b/issues/toyos-explains-itself.md @@ -79,7 +79,7 @@ thermal counters, the log's steps, accounting, `inspect` and `size`. manifest row names; a program without the counters right is refused a counter read, and one that holds it but not `trace` is refused the power and per-device interrupt counters; and a T14 row holds each counter ToyOS reads -there to the bound Intel's SDM gives it, as `counters_on_metal` holds the busy +there to the bound Intel's SDM gives it where it gives one, as `counters_on_metal` holds the busy clock to base frequency. Linux's reading of each counter is a goal compared in evidence (`issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md`), diff --git a/tests/toyos.rs b/tests/toyos.rs index 6b1d56a6456..8a4bde6ce5d 100644 --- a/tests/toyos.rs +++ b/tests/toyos.rs @@ -5060,12 +5060,12 @@ const SMI_SPAN_NS: u64 = 4_444_000_000; /// moves by the commands the kernel wrote to `SMI_CMD` in that span and by /// nothing else: every firmware interrupt is one ToyOS asked for. Across the spin every /// CPU's MPERF ran nine tenths of its stamp or more [e], a CPU in C0 the whole -/// span: MPERF counts at the TSC's rate there (SDM Vol. 3B, "Hardware -/// Coordination Feedback"); and every CPU's APERF ran at least as fast as its -/// MPERF across the spin, its busy clock at or above its base frequency: MPERF -/// counts at close to the maximum non-turbo frequency and APERF at the actual -/// one (SDM Vol. 3B §22.7.2), so a spinning CPU below it is held there by its -/// request, a power limit or firmware. +/// span: MPERF counts at a fixed rate, the TSC's, and APERF at the actual +/// clock (SDM Vol. 3B §22.7.2, 325462-093); and every CPU's APERF ran at +/// least as fast as its MPERF across the spin, its busy clock at or above the +/// rate MPERF counts at (2419.2 MHz on the T14). A spin under a request whose +/// maximum is `Highest_Performance` falls below it only when a power limit or +/// firmware holds the CPU there. /// /// Read and not held: each CPU's idle busy fraction, which an SMI in the idle /// second raises on every CPU alike by the time it held them, its spinning @@ -5206,7 +5206,7 @@ fn counters_on_metal(back: &metal::Readback) -> Result<(), String> { for said in log.text().lines().filter(|l| l.contains("counters_metal loaded: ")) { eprintln!(" [counters] {}", said.split("counters_metal ").nth(1).unwrap_or(said).trim()); } - let above_base: Vec = (0..cpus).map(|cpu| ratio(idle1, spin, cpu, "aperf", "mperf")).collect(); + let aperf_per_mperf: Vec = (0..cpus).map(|cpu| ratio(idle1, spin, cpu, "aperf", "mperf")).collect(); eprintln!( " [counters] {cpus} cpus, the SMI count on each moved by {asked} over {} ms, the commands the kernel wrote to SMI_CMD in it; TSC {tsc_mhz:.0} MHz", (at2 - at0) / 1_000_000 @@ -5215,12 +5215,12 @@ fn counters_on_metal(back: &metal::Readback) -> Result<(), String> { eprintln!( " [counters] cpu{cpu}: idle busy {:.2}%, spinning {:.0} MHz, busy {busy:.3}", ratio(idle0, idle1, cpu, "mperf", "stamp") * 100.0, - tsc_mhz * above_base[cpu], + tsc_mhz * aperf_per_mperf[cpu], ); } eprintln!(" [counters] the spin's read, a whole round, took its reader {} ns", clock["spin"].1); - if above_base.iter().any(|&r| r < 1.0) { - return Err(format!("APERF ran {above_base:.3?} of MPERF across the spin, some cpu below its base frequency")); + if aperf_per_mperf.iter().any(|&r| r < 1.0) { + return Err(format!("APERF ran {aperf_per_mperf:.3?} of MPERF across the spin, some cpu's busy clock below the rate MPERF counts at")); } Ok(()) } From d29e6cb28f3c94a0d41619a4cb7a10febed75909 Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 14 Oct 2026 20:17:33 +0200 Subject: [PATCH 5/6] suite-rows: the counters floor is at the rate MPERF counts at Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016UzbDnM9m6nQWhbjGi6Lv1 --- .../suite-rows-that-are-measurements-or-make-several-claims.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/issues/suite-rows-that-are-measurements-or-make-several-claims.md b/issues/suite-rows-that-are-measurements-or-make-several-claims.md index 633cb37fdf5..80fb18b9ad7 100644 --- a/issues/suite-rows-that-are-measurements-or-make-several-claims.md +++ b/issues/suite-rows-that-are-measurements-or-make-several-claims.md @@ -20,7 +20,7 @@ Measurements as `METAL` rows in `tests/toyos.rs`: - `counters` (`counters_on_metal`): records fresh and named by APIC id, SMI counts moved only by the kernel's commands, MPERF against the stamp, an idle second with no log line, the HWP request - and a base-frequency floor. The HWP request's oracle is + and a floor at the rate MPERF counts at. The HWP request's oracle is `issues/t14-rows-hold-toyos-to-linuxs-choice-or-copy.md`'s. - `acpi_tables_loaded` (`acpi_tables_on_metal`): the definition-block count, the MTRRs compared across CPUs, nothing refused, and the AML reads. The count's oracle is the same issue's. From 572b6c9820160c374d6d21ab6309c9d265f8395c Mon Sep 17 00:00:00 2001 From: japabu Date: Wed, 14 Oct 2026 20:18:05 +0200 Subject: [PATCH 6/6] toyos-explains-itself: the counters row holds the busy clock to MPERF's rate, not base frequency Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016UzbDnM9m6nQWhbjGi6Lv1 --- issues/toyos-explains-itself.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/issues/toyos-explains-itself.md b/issues/toyos-explains-itself.md index 1f5589d222c..ab2bb2b0ab5 100644 --- a/issues/toyos-explains-itself.md +++ b/issues/toyos-explains-itself.md @@ -80,7 +80,7 @@ manifest row names; a program without the counters right is refused a counter read, and one that holds it but not `trace` is refused the power and per-device interrupt counters; and a T14 row holds each counter ToyOS reads there to the bound Intel's SDM gives it where it gives one, as `counters_on_metal` holds the busy -clock to base frequency. Linux's reading of each counter is a goal compared in +clock to the rate MPERF counts at. Linux's reading of each counter is a goal compared in evidence (`issues/linuxs-readings-of-the-t14-and-the-tcg-model-lack-reads-owed-before-the-t14s-wipe.md`), never a row's expected value.