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..158f090784b 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,17 @@ 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, 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, 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 4b6ad61c4fe..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,17 +13,19 @@ 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**: 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 -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. 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/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/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..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 turbostat 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. 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 582c621de60..00000000000 --- a/issues/the-tree-names-linux-as-an-authority.md +++ /dev/null @@ -1,36 +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**: `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. 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/toyos-explains-itself.md b/issues/toyos-explains-itself.md index b5bc757632e..ab2bb2b0ab5 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 where it gives one, as `counters_on_metal` holds the busy +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. 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 748bf0beeda..8a4bde6ce5d 100644 --- a/tests/toyos.rs +++ b/tests/toyos.rs @@ -588,7 +588,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"])], @@ -5060,16 +5060,18 @@ 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 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`). +/// 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, 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")?; @@ -5200,60 +5202,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 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 ); 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 * aperf_per_mperf[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 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(()) } /// 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")?; @@ -5559,15 +5537,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 ")?; @@ -5583,6 +5565,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").