Skip to content
33 changes: 33 additions & 0 deletions issues/build/no-gate-decodes-kernel-elfs-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
status: open
kind: tooling
opened: 2026-09-29
---

# No gate decodes `kernel.elf`'s instructions

Five stages each owe a gate over `kernel.elf`'s instructions:

- `issues/kernel/no-entry-or-switch-clears-the-bhb-fills-the-rsb-or-issues-an-ibpb.md`
- `issues/kernel/indirect-branches-and-returns-run-without-thunks.md`
- `issues/kernel/kernel-functions-return-with-their-used-registers-intact.md`
- `issues/kernel/the-kernel-runs-without-indirect-branch-tracking.md`
- `issues/kernel/kernel-forward-copies-and-fills-are-one-rep-movsb-or-stosb-on-every-cpu.md`

The five share one x86-64 decoder, in Rust in the tree and run by the host
gate, with no external disassembler: it lands before any of them, and each adds
its own check over it rather than a decoder of its own. It takes its functions
from `toyos_symbols::locate` over `toyos_elf` (`src/build.rs:1575-1598`), not
from a second ELF reader. `global_asm!` emits no `.type` or `.size`, so code
such as the AP trampoline (`kernel/src/arch/x86_64/smp.rs:396`), in `.text`
with a `jmp far [mem]` and a `retf`, is covered by no sized function.

**Exit**: the decoder walks every function `kernel.elf`'s `.symtab` names, from
its address to its size, and a walk that decodes a byte it does not know or
ends anywhere but the function's end is refused; so is any byte of an
executable section that no walked function covers, apart from a region named by
symbol and decoded in its own mode, as the trampoline's 16-, 32- and 64-bit
code is. **Mutation**, each red over the shipped kernel: an instruction length
misread by one, a SIB byte dropped after a ModRM r/m of 100b;
`global_asm!("1: jmp rax")` in `.text`. **Oracle**: SDM Vol. 2's opcode maps,
Appendix A.
18 changes: 18 additions & 0 deletions issues/hardware/blockd-drives-nvme-apst.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
status: open
kind: track
opened: 2026-09-29
---

# blockd drives NVMe APST

After blockd drives the T14's drive, the blockd step of
`issues/kernel/the-kernel-is-small-interrupts-post-and-threads-wait.md`. As
Linux at `Ubuntu-6.8.0-142.142`, APST stays within
`default_ps_max_latency_us` and honours `NVME_QUIRK_NO_APST` and
`NVME_QUIRK_NO_DEEPEST_PS` (`drivers/nvme/host/core.c:63,2495-2598`).

**Exit**: host tests of the APST table; on the T14, the one proving machine
with a physical NVMe drive, the block figures and the idle minute with the
drive idle. **Mutation**: a table that admits a state past the bound.
**Oracle**: Linux's `nvme_configure_apst` over the T14's `id-ctrl`.
47 changes: 47 additions & 0 deletions issues/hardware/features-no-proving-machine-is-known-to-offer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
status: open
kind: track
opened: 2026-09-29
---

# Features no proving machine is known to offer

No stage of
`issues/kernel/the-kernel-is-at-least-as-secure-as-linux-on-every-machine-toyos-supports.md`
or `issues/kernel/toyos-uses-what-modern-hardware-offers-for-speed.md` takes
these, since neither the T14 nor a nightly EPYC KVM guest is known to
enumerate one. It is blocked on a proving machine that does; its exit is every
row a stage issue under the track it serves, or a `rejected` issue. Intel's
parts are named by the SDM 325462-093US, Vol. 1 Table 5-2 ("SDM"), or by the
ISE reference 319433-062, Table 1-2 ("ISE"), neither of which places any of
these in Tiger Lake. AMD's and Arm's are read in Linux at tag `v7.2`; the AMD
parts that carry each were not verified against AMD's documents, and the Arm
cores were not verified against Arm's. The Arm rows belong to
`issues/kernel/toyos-runs-on-arm64.md`'s CPU-state declaration.

| Feature | Hardware |
|---|---|
| FRED and LKGS | Panther Lake, Clearwater Forest, Diamond Rapids (ISE) |
| LASS | Sierra Forest, Atom P6900, Core Ultra 200H (SDM) |
| LAM | the parts LASS names (SDM) |
| PKS | Alder Lake, Sapphire Rapids, Sierra Forest (SDM) |
| User interrupts (UINTR) | Sapphire Rapids, Sierra Forest, Atom P6900, Core Ultra 200H (SDM) |
| UMONITOR, UMWAIT, TPAUSE | Tremont, Alder Lake, Sapphire Rapids (SDM) |
| Fast zero-length `rep movsb`, fast short `rep stosb` | Alder Lake, Sapphire Rapids (SDM) |
| AMX | Sapphire Rapids (SDM) |
| AVX10.1, AVX10.2 | AVX10.1: Granite Rapids, Nova Lake; AVX10.2: Diamond Rapids, Nova Lake (ISE) |
| APX | Diamond Rapids, Nova Lake (ISE) |
| Thread Director, HRESET | Alder Lake (SDM) |
| TDX | Emerald Rapids (ISE) |
| Total Storage Encryption | Panther Lake (ISE) |
| TME | 11th-generation Core lines that set CPUID.(7,0):ECX bit 13, which varies by line (datasheet 631121-012 §1.3); the T14 reads ECX 0x18c05fde, bit 13 clear |
| INVLPGB, TLBSYNC | AMD, CPUID 0x80000008:EBX bit 3 (`arch/x86/include/asm/cpufeatures.h:331,335`); whether a nightly EPYC guest sees it waits on its runner's CPUID capture |
| SEV-SNP | AMD, CPUID 0x8000001F:EAX bit 4 (`cpufeatures.h:448,453`) |
| Shadow stack on AMD | AMD; unverified: that AMD enumerates it through the bit Linux reads for Intel, CPUID.(7,0):ECX bit 7 (`cpufeatures.h:390,397`), and which parts set it; whether a nightly EPYC guest sees it waits on its runner's CPUID capture |
| MTE | Armv8.5 (`arch/arm64/Kconfig:2150-2170`) |
| Pointer authentication | Armv8.3 (`arch/arm64/Kconfig:1967-1974`) |
| BTI | Armv8.5 (`arch/arm64/Kconfig:2087-2093`) |
| GCS | Armv9.4 (`arch/arm64/Kconfig:2236-2254`) |
| POE | Armv8.9 (`arch/arm64/Kconfig:2198-2213`) |
| SME | Arm (`arch/arm64/Kconfig:2311-2319`) |
| NVMe host memory buffer | an NVMe drive whose `id-ctrl` reads HMPRE non-zero; the T14's has not been read, and blockd builds the buffer only once a proving machine's does |
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
status: assigned
kind: tooling
opened: 2026-09-29
---

# Linux's readings of the T14 and the TCG model are not committed

The floor of
`issues/kernel/the-kernel-is-at-least-as-secure-as-linux-on-every-machine-toyos-supports.md`
is tag `Ubuntu-6.8.0-142.142` (53e5d07aac028a1523ab0b115f079d6d1bc831ef) of
`https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/noble`,
config sha256 3b8533dd9d235ca634ac58f82c5ce1ee35f12ef620693e17033184d2c9ca5890,
and what it reads on the T14 and on the PR gate's TCG model are the fixtures
of `issues/kernel/a-pure-function-decides-a-cpus-speculation-mitigations-as-linux-does.md`.
Pull request #601 holds it. Ubuntu leaves the T14 only after this issue and
`issues/hardware/no-program-measures-toyos-against-linux-on-one-machine.md`
close.

**Exit**: both captures committed, and no Linux image; before the wipe the
T14's adds CPUID 5, 0x19 and 0x80000001, MSR 0xCF, the split-lock line, and
the config's `X86_KERNEL_IBT` and `X86_INTEL_MEMORY_PROTECTION_KEYS`.
**Mutation**: a config hash off by one byte is refused. **Oracle**: that
Linux.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
status: open
kind: tooling
opened: 2026-09-29
---

# No program measures ToyOS against Linux on one machine

One Rust program, built for `x86_64-unknown-linux-gnu` and for ToyOS, is to
measure memcpy from 64 B to 64 MiB; AES-128-GCM, ChaCha20-Poly1305 and SHA-256
at sshd's RustCrypto versions; pipe round trips, and throughput at 64 B to 64
KiB; munmaps per second of a page a sibling on another CPU touched; lateness
past a 1 ms timer; NVMe reads, read-only; an idle minute's package energy; and
the T14's PCI, USB, NVMe and cpuidle identity. It runs on the T14 under its
Ubuntu before the wipe and under the shipped ToyOS kernel. A munmap pair's two
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.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ under the T14's `CONFIG_INTEL_IOMMU_DEFAULT_ON=y` and
`CONFIG_IOMMU_DEFAULT_DMA_LAZY=y`, turns DMA remapping on
(`drivers/iommu/intel/iommu.c:227`) and gives every device a translated
default domain (`drivers/iommu/iommu.c:197-210`), which maps only what its
driver maps. A row of the
hardening table in
`issues/kernel/the-kernel-mitigates-what-linux-mitigates-on-the-t14.md`.
driver maps.

**Exit**: a function's DMA reaches only what its driver mapped and the reserved
ranges firmware names for it; a `boot-actuators` arm that points an unclaimed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
status: assigned
kind: track
opened: 2026-09-29
---

# A pure function decides a CPU's speculation mitigations as Linux does

From a CPU's facts to the line Linux at `Ubuntu-6.8.0-142.142` prints in each
`/sys/devices/system/cpu/vulnerabilities/*` file and the mitigation it
selects, built by the kernel and by a host test. Pull request #602 holds it.

**Exit**: each committed fixture's facts give its lines: the T14's and the TCG
model's from
`issues/hardware/linuxs-readings-of-the-t14-and-the-tcg-model-are-not-committed.md`,
and each nightly EPYC guest's once its runner is captured. **Mutation**: `GDS`
deleted from `cpu_vuln_blacklist`'s TIGERLAKE_L row reds the T14's fixture,
and `SRSO` deleted from its family 0x19 row reds a family-0x19 EPYC guest's.
**Oracle**: those lines, and Linux's `cpu_vuln_whitelist` and
`cpu_vuln_blacklist` row for row
(`arch/x86/kernel/cpu/common.c:1182-1244,1284-1344`).
17 changes: 17 additions & 0 deletions issues/kernel/a-split-lock-goes-unnoticed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
status: open
kind: defect
opened: 2026-09-29
---

# A split lock goes unnoticed

The kernel never sets `MSR_TEST_CTRL` (0x33) bit 29, so a user `lock`
instruction across a cache line locks the bus for every CPU and nothing
reports it. Linux at `Ubuntu-6.8.0-142.142` detects it by default and warns
(`sld_warn`, `arch/x86/kernel/cpu/intel.c:1083`); ToyOS ends the process by
name instead.

**Exit**: on the T14, the one proving machine known to enumerate split-lock
detection, a `lock add` across a line is ended by name. **Mutation**: bit 29
clear. **Oracle**: the T14's CPU.
3 changes: 1 addition & 2 deletions issues/kernel/a-threads-kernel-stack-has-no-guard-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ write. The per-CPU idle stacks already have an unmapped page below them
(`kernel/src/arch/x86_64/percpu.rs:482`). Linux at `Ubuntu-6.8.0-142.142`,
under the T14's `CONFIG_VMAP_STACK=y`, maps every task stack in vmalloc space
between guard pages (`kernel/fork.c:314-318`, `arch/Kconfig:1327-1336`), so
the first write past the end faults. A row of the hardening table in
`issues/kernel/the-kernel-mitigates-what-linux-mitigates-on-the-t14.md`.
the first write past the end faults.

**Exit**: every thread's kernel stack has an unmapped page below it; a
`boot-actuators` arm that recurses a thread past its stack gets a double fault
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
status: open
kind: track
opened: 2026-09-29
---

# A TLB shootdown reaches only the CPUs that ran the space

A shootdown blocks on every other CPU (`kernel/src/mm/unmapped.rs:5`),
whether or not it ever ran the address space. It waits on
`issues/kernel/no-test-can-hold-a-thread-on-a-named-cpu.md`. A CPU that
switches away keeps the space's entries: under PCID every CR3 load sets
NOFLUSH (`kernel/src/arch/x86_64/paging.rs:295-306`), so a CPU leaves the
target set only when those entries are gone, not when it stops running the
space. The TCG model has no PCID (`src/arch.rs:169`), so only a machine with
PCID can show a switched-out CPU still holding them.

**Exit**: on every proving machine and under TCG, a sibling pinned on another
CPU touches a page the initiator unmaps and then faults; on each proving
machine with PCID, the sibling touches the page and blocks off its pinned CPU,
the initiator unmaps it while the sibling is blocked and a thread of another
space runs there, and the sibling faults on touching it again after it wakes
there; cases in `kernel-loom/tests/tlb_shootdown.rs` switch a CPU into the
space, and out of it, while the initiator reads the target set; the T14's
munmap figure. **Mutation**, each red: a target set that omits a CPU the space
ran on; a CPU that joins the set after loading CR3; a CPU cleared from the set
when it switches away from the space, its red recorded over repeated runs,
since it rests on the TLB keeping the entry across the block. **Oracle**: loom,
and each proving machine's TLB.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
status: open
kind: track
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/hardware/linuxs-readings-of-the-t14-and-the-tcg-model-are-not-committed.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.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ Linux at `Ubuntu-6.8.0-142.142`, under the T14's
offset at every syscall entry (`arch/x86/entry/common.c:73`,
`include/linux/randomize_kstack.h:40,50`), drawn on the exit before it
(`arch/x86/include/asm/entry-common.h:85`), 7 bits after alignment on x86-64
(`entry-common.h:76-83`). A row of the hardening table in
`issues/kernel/the-kernel-mitigates-what-linux-mitigates-on-the-t14.md`.
(`entry-common.h:76-83`).

**Exit**: every syscall's handler runs below an offset drawn per syscall, of at
least 7 bits; a `boot-actuators` probe records one handler frame's address
Expand Down
21 changes: 21 additions & 0 deletions issues/kernel/fsgsbase-is-measured-then-taken-or-rejected.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
status: open
kind: track
opened: 2026-09-29
---

# FSGSBASE is measured, then taken or rejected

`CR4.FSGSBASE` is forbidden (`kernel/src/arch/x86_64/control_regs.rs:62-75`):
GS always holds the kernel's per-CPU base and the kernel runs no `swapgs`.
Taking it costs a `swapgs` entry and the swapgs barriers of
`issues/kernel/user-pointer-checks-have-no-spectre-v1-fence-and-smap-is-optional.md`.

**Exit**: the T14's pipe round trips with and without it, a loss becoming a
`rejected` issue with both figures. Taken: on every proving machine and under
TCG, a `boot-actuators` arm enters vector 2 at CPL 0 while the user GS base is
live, between entry and its `swapgs` or after the exit path's, and the handler
finds the kernel's per-CPU data; `CR4_FORBIDDEN`, the `user-writable-gsbase`
kernel (`src/build.rs:1370`) and the test `gsbase_locked` are deleted.
**Mutation**: an IST entry that decides `swapgs` from the saved CS alone.
**Oracle**: Linux's `paranoid_entry`.
16 changes: 16 additions & 0 deletions issues/kernel/idle-cpus-enter-the-c-states-cst-names.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
status: open
kind: track
opened: 2026-09-29
---

# Idle CPUs enter the C-states `_CST` names

The kernel runs no `mwait` and reads no `_CST`. The states come from `_CST`,
as Linux takes the T14's, after the AML interpreter that
`issues/kernel/the-scheduler-and-the-clocks-never-talk.md` waits on.

**Exit**: on the T14, since a KVM guest's idle is its host's: the idle
minute's package energy, and timer lateness no worse than `hlt`'s by more than
the chosen state's exit latency. **Mutation**: always the deepest state.
**Oracle**: Linux's figures.
30 changes: 30 additions & 0 deletions issues/kernel/indirect-branches-and-returns-run-without-thunks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
status: open
kind: defect
opened: 2026-09-29
---

# Indirect branches and returns run without thunks

Nothing in the kernel's build asks for a retpoline, a return thunk or
straight-line-speculation padding. Linux at `Ubuntu-6.8.0-142.142` builds with
`MITIGATION_RETPOLINE`, `MITIGATION_RETHUNK`, `MITIGATION_ITS` and `SLS`
(`debian.master/config/annotations:8043-8045,12190`) and installs the return
thunk its decision selects: ITS's on the T14; on AMD, retbleed's untrained
return (`arch/x86/kernel/cpu/bugs.c:1125`) or SRSO's safe RET, in its alias
form on family 0x19 (`bugs.c:2726-2732`).

**Exit**: a gate over `kernel.elf`, on the decoder of
`issues/build/no-gate-decodes-kernel-elfs-instructions.md`, finds no raw
indirect branch or `ret` outside the thunks and entry, an `int3` after each, and every placement Linux's linker
script asserts (`arch/x86/kernel/vmlinux.lds.S:510-539`):
`retbleed_return_thunk` and `srso_safe_ret` at a line start, the SRSO alias
pair's addresses differing in exactly bits 2, 8, 14 and 20, and each ITS
thunk's branch in its line's upper half. Each proving machine's boot installs
the thunks the decision selects for it: ITS's on the T14, SRSO's alias on a
family-0x19 EPYC guest. No proving machine is family 0x17, so the untrained
return is proven by the gate and the decision's host test alone.
**Mutation**, each red: an ITS thunk at a line start; `retbleed_return_thunk`
one byte past its line start; the SRSO alias one cache line off its pair; an
`int3` gone; ITS's thunk installed on every CPU. **Oracle**: that linker
script, and `Documentation/admin-guide/hw-vuln/indirect-target-selection.rst`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
status: open
kind: track
opened: 2026-09-29
---

# Kernel forward copies and fills are one `rep movsb` or `rep stosb` on every CPU

The kernel's `memcpy`, `memset` and `memmove` are `compiler_builtins`', which
frame `rep movsq` or `rep stosq` with two byte strings, and take one `rep movsb`
or `rep stosb` only when built with the `ermsb` target feature
(`rust/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs:15-17,23-58,88-126`);
`memmove`'s backward branch, `copy_backward` (`:62-85`), keeps `rep movsq`
either way. The kernel links the sysroot's `compiler_builtins`, which no kernel
build flag recompiles: the feature is `rustflags = ["-Ctarget-feature=+ermsb"]`
under `[target.x86_64-unknown-none]` in the std build's `bootstrap.toml`
(`std_config`, `src/sysroot.rs:522`; bootstrap's `core/config/toml/target.rs:41`),
and it moves the sysroot key (`RECIPE`, `src/sysroot.rs:65`), which reaches
CI's installed toolchain only once the release tag's `trees()`
(`src/release.rs:25-31`) hashes `src/sysroot.rs`, the work of
`issues/build/the-release-tag-hashes-none-of-the-build-system-that-builds-the-toolchain.md`,
which lands first. One path on every
CPU: `rep movsb` is correct without ERMS, CPUID.(7,0):EBX bit 9, and no CPU is
refused. Zen 2 lacks ERMS (a Ryzen 9 PRO 3900, family 0x17, reads EBX
0x219C91A9: InstLatx64 ddff8a92,
`AuthenticAMD/AuthenticAMD0870F10_K17_Matisse_CPUID.txt:52`), and no proving
machine is family 0x17.

**Exit**: a gate over `kernel.elf`, on the decoder of
`issues/build/no-gate-decodes-kernel-elfs-instructions.md`, finds `memcpy`,
`memset` and `memmove`'s forward branch each one `rep movsb` or `rep stosb`,
with no `rep movsq` or `rep stosq`; the T14's pipe figures; and Zen 2's cost
recorded, as a family-0x17 figure against the build without `ermsb` or as a
`tooling` issue that owes it. **Mutation**: the build without `ermsb` reds the
gate. **Oracle**: Linux's pipe figures.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ builds with `-fzero-call-used-regs=used-gpr` (`Makefile:891-894`). LLVM acts
on the function attribute `zero-call-used-regs`
(`llvm/lib/CodeGen/PrologEpilogInserter.cpp:1212`), and the rustc fork at
1b236638 has no option that sets it
(`compiler/rustc_session/src/options.rs`). A row of the hardening table in
`issues/kernel/the-kernel-mitigates-what-linux-mitigates-on-the-t14.md`.
(`compiler/rustc_session/src/options.rs`).

**Exit**: the kernel, `core` and `alloc` build under a rustc option that sets
`zero-call-used-regs=used-gpr` on every function, carried in the fork to
upstream quality; a gate over `kernel.elf` finds each function's used
upstream quality; a gate over `kernel.elf`, on the decoder of
`issues/build/no-gate-decodes-kernel-elfs-instructions.md`, finds each function's used
call-clobbered general registers zeroed before its return thunk, and a build
without the option reds it.
Loading
Loading