Skip to content

Commit a93067f

Browse files
authored
ABI: a deleted syscall, SYS_DEBUG action or inbox op is simply deleted (#651)
A removed number is free (root `CLAUDE.md`, #673). This is the code half: no source file holds a retirement entry for a deleted syscall, `SYS_DEBUG` action, inbox op or device class any more, and a deleted one answers as a number nobody ever assigned. No live number moves. It closes `issues/design-debt/the-abi-still-keeps-retired-syscall-numbers.md`. ## What changed, per decision - **The kernel's retired table is gone** (`kernel/src/syscall/dispatch.rs`): `retired_syscalls!`, its 19 entries and its ascending-order assert. A number no arm claims falls to the one default arm, `_ => SyscallError::InvalidArgument.to_u64()`. - **The default arm writes no record.** The retired arm logged each call. Any process can reach the default arm at syscall rate with no authority, so a record there is a log flood any program can make. What the kernel keeps of such a call is a count, not a name: the exit-time `syscalls: pid=…` record gives the main thread's calls per number, and every number at or past `SYSCALL_PROFILE_OTHER`, 127, shares its last bin. The T14's call of `u64::MAX` reads `127=1`. - **Every retirement entry is deleted** from `toyos-abi/src/syscall.rs` and `toyos-abi/src/inbox.rs`: the "formerly …" and "retired and unused" notes for syscall numbers, for `SYS_DEBUG` actions 8, 14, 15, 17 and 18, for device classes 3 and 4 and for inbox ops 2 and 4; the paragraphs on why 76 and 89 kept their numbers; the 113 and 115 reservations; and the `"nic"` case of the `DeviceRequest` parse test. The clauses that leaned on them go from `toyos-abi/src/inventory.rs`, `kernel/src/inbox/mod.rs` and `toyos/src/census.rs`. - **`inventory.rs`'s refused-class test** takes one past the highest declared `DeviceType` and `1 << 40`, not 3 and 4, which the next class may take. - **`panic_halts_first` makes its records with `SYS_DEBUG` `LOG_PATTERNED`.** Its siblings' record was the retired arm's `syscall 26 is retired`. `virt_fatal_halts_the_others_first`'s judge reads `logstorm t=0 i=0 ` from another CPU as its non-vacuity. What the test judges is unchanged: QEMU's own account, over QMP, of every other vCPU halted on AArch64 `virt`, a machine the T14 is not. - **`syscall_unassigned` pins the default arm's word.** Round 1's mutation, the arm answering `NotSupported`, left every test green. The binary calls `u64::MAX` past the wrappers and asserts `InvalidArgument`. - One number: the one thing computed from the number before the match is the profile's index, `(num as usize).min(SYSCALL_PROFILE_OTHER)`, and `u64::MAX` is the number that reaches its clamp. - Not a once-retired number: a test that names 26 holds 26 against the next syscall. - Its tier: no type holds an error word, and the kernel crate builds for no host. It is a discovered binary, so it rides the T14's shared boot on the shipping kernel and adds no QEMU test. - **Issues.** The plans that followed the rule lose it: `sys-clock-realtime…`, `the-kernel-still-parses…`, `the-capability-end-state…`, `the-kernel-keeps-nothing-it-enumerates`, `no-cyclictest`, `mio-deregister…`, `the-kernel-is-small…`, `the-supervisor-is-host-tested…` and `sys-debug-actions-and-two-loader-words-that-nothing-calls`. The last also records that `LOG_PATTERNED` has a caller again and that the pattern `kernel/src/log/storm.rs` writes into the record has no reader. Filed: `issues/design-debt/the-window-protocol-keeps-a-retired-message-type.md`, the same legacy in the window protocol, which waits on `issues/isolation/the-compositor-ignores-a-message-it-does-not-know.md`. - **The AArch64 half of the test binaries' assembly is deleted** (`tests/toyos-rust-tests/src/arch/aarch64.rs` and the selector's arm). On main `panic_halts_first` ran it on `virt`; `arch`'s one includer is now `syscall_unassigned`, and the harness builds that for x86-64 alone. - **Not touched, and recorded**: six comments that name a deleted syscall as history and hold no number. `issues/design-debt/comments-still-name-syscalls-the-abi-deleted.md` names each site, their owner and the exit. `toyos-i219`'s exit code 82 is no ABI number. - **Not touched**: four issues that tell history name a deleted number. `issues/build/mio-deregister-fd-leaves-a-pending-poll-live.md` quotes op code 2's old comment as the evidence of its defect, `issues/diagnostics/no-cyclictest.md` names `SYS_SET_RT_PRIORITY` (96) as the gate it was opened against, and `issues/build/parallel-tests-red-under-other-suites.md` and `issues/kernel/deferred-release-outlives-its-syscall.md` name the commits that deleted `SYS_DEBUG` actions 8, 17 and 18. Net against `origin/main` 5daab30: `23 files changed, 103 insertions(+), 269 deletions(-)`. | | Insertions | Deletions | |---|---|---| | Production: kernel, `toyos-abi`, `toyos` | 2 | 159 | | Tests: guest binaries, the judge, `toyos-abi` unit tests | 26 | 39 | | Issues | 75 | 71 | ## Gates at b20bc9d b20bc9d is b198b3a, the head the review's named changes were made at, merged with `origin/main` 5daab30 (#655). The merge had no conflict: git merged `toyos-abi/src/inbox.rs` and `kernel/src/inbox/mod.rs` on its own, and in both #655's addition and this branch's deletion are in the result. `git diff b198b3a b20bc9d` is #655's diff line for line, and it touches neither `kernel/src/syscall`, `toyos-abi/src/syscall.rs`, `tests/toyos.rs` nor either test binary of this change. #655 brought no retirement entry and no mention of a deleted number: every search of the tree for one gives the same hits at b198b3a and at b20bc9d, and none matches a line #655 added. The searches and their results are in the gates comment linked below. | Command | EXIT | |---|---| | `cargo run -- --ci host` (67 steps, clippy over every kernel shape among them) | 0 | | `cargo run -- --build-only` | 0 | | `cargo test` (the 25 guest tests, `virt_fatal_halts_the_others_first` among them) | 0 | | `cargo test --test toyos-build -- --metal --metal-readback <dir> syscall_unassigned`, staging | 2: staged | | the same command over the T14's readback of that image | 0: 1 passed, 0 failed, 1 boot | Their logs, by key line and exit: [the gates at b20bc9d](#651 (comment)). `origin/main` has since moved to 8f6abbc (#657), which this head does not hold: 11 files, none of them one this branch changes, and `git merge-tree --write-tree b20bc9d 8f6abbc` exits 0. Nothing above was measured with #657. The T14 booted b20bc9d's image once, run by the orchestrator ([the boot](#651 (comment))): the shared boot with the one job `test_rs_syscall_unassigned`, sha256 `e6471fa75b3d703645e1c617dda6f212dfb8415e3466e794ba3189ee92106a8e` checked before it was flashed, `toyos-metal` exit 0, `===TEST_END test_rs_syscall_unassigned exit=0===`, the judge exit 0. The earlier readings are ea0ee48's ([the boot](#651 (comment))) and b198b3a's ([the boot](#651 (comment))), both on main without #655. At each: that head's image, its sha256 checked before it was flashed (`6b031ff614c73a644ceb391eee5cb190db21cb124c03a20ef4724521455527ce` and `e52fbc8437d1fed1df3db45c26e33a1f68454829f35b548eddef4004533366b6`), `toyos-metal` exit 0, `===TEST_END test_rs_syscall_unassigned exit=0===`, and the judge over its readback exit 0, 1 passed, 0 failed, 1 boot. No mutation was booted on the machine, and the red arms below are QEMU's. ## The checks of a change to the ABI Each arm is `cargo test --test toyos-build -- <filter>` on ea0ee48, before the review's named changes and the merge of #655, under a checked patch, restored afterwards; the patches and the script are in [that round's comment](#651 (comment)). None was run again at b20bc9d. The probe harness, not landed, boots `tests/testcases` on the shipping kernel under QEMU and runs `test_rs_syscall_unassigned`. | Arm | Filter | EXIT | |---|---|---| | The probe harness alone | `qemu_syscall_unassigned` | 0 | | The default arm answers `NotSupported` (round 1's mutation) | `qemu_syscall_unassigned` | 1: `syscall 18446744073709551615 answered 0xfffffffffffffff7` | | The whole change reverted but for the new test | `qemu_syscall_unassigned` | 0 | | 26 probed beside `u64::MAX` | `qemu_syscall_unassigned` | 0: both `InvalidArgument` | | 26 probed, and the whole change reverted but for the new test | `qemu_syscall_unassigned` | 1: 26 answers `NotSupported` | | `panic_halts_first.rs` and its judge reverted to main's, on this kernel | `virt_fatal_halts_the_others_first` | 1: `no other CPU made a record before the fatal one on cpu3` | - **Negative control.** The whole change reverted is red only for a probe of a once-retired number, the fifth arm, and the landed test probes none, the third: the revert restores an answer for 19 numbers nothing may name any more. The sixth arm is the control of the test this change moved: without its new record source it is red, not vacuous. - **Oracle.** rustc, in every kernel shape of the host gate and in the image build: nothing still names `retired_syscall`. The declared numbers are main's: the `const` and device-class lines of `toyos-abi/src/syscall.rs` (129) and `toyos-abi/src/inbox.rs` (12) at 5daab30 and at b20bc9d `diff` with exit 0. `git grep -E 'retired_syscall|RETIRED_SYSCALLS' b20bc9d` and `git grep -i -E 'formerly|retired and unused|never reused|reserved, not free' b20bc9d -- toyos-abi toyos kernel/src/syscall kernel/src/inbox` both exit 1. For `virt_fatal_halts_the_others_first`, QEMU's QMP says which vCPUs halted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm
2 parents c59e09e + b20bc9d commit a93067f

23 files changed

Lines changed: 103 additions & 269 deletions

‎issues/build/mio-deregister-fd-leaves-a-pending-poll-live.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ notification for a resource it was promised was gone.
3434

3535
There used to be an ABI op for this. `toyos-abi/src/inbox.rs` op code 2 was
3636
`IORING_OP_POLL_REMOVE`, retired in PR #89 (`c41b831`,
37-
"abi: four names retired, and the number each one held") as caller-less. The
38-
retirement's own reasoning is recorded at the site:
37+
"abi: four names retired, and the number each one held") as caller-less:
3938

4039
```
4140
// Op code 2 unused (formerly IORING_OP_POLL_REMOVE). It had no submitter
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
status: open
3+
kind: defect
4+
opened: 2026-10-02
5+
---
6+
7+
# Comments still name syscalls the ABI deleted
8+
9+
A deleted syscall is simply deleted, and a past implementation lives in a commit
10+
message, never in source. Six comments still tell the history of a syscall
11+
`toyos-abi` no longer declares:
12+
13+
- `userland/libc/src/misc.rs`, `waitpid`'s doc: "`SYS_WAITPID` is retired";
14+
- `kernel/src/pipe.rs`, `Pipe::backing`'s doc: a pending `SYS_CONNECT`;
15+
- `userland/soundd/src/virtio.rs`, `submit`'s doc: "the deleted
16+
`SYS_AUDIO_SUBMIT`";
17+
- `tests/toyos-rust-tests/src/bin/abuse_pipe_owner.rs`, the module doc:
18+
`SYS_PIPE_OPEN` and `SYS_SOCKET_CREATE`, "that family is retired";
19+
- `tests/toyos-rust-tests/src/bin/abuse_connect_flood.rs`, the module doc:
20+
"it used to `SYS_LISTEN`";
21+
- `tests/toyos-rust-tests/src/bin/shm_release_reclaims.rs`, the module doc:
22+
what `SYS_RELEASE_SHARED` did.
23+
24+
None holds a number or refuses anything, so none is a retirement entry. Each is
25+
deleted down to what is true of its item now.
26+
27+
Owner: the item each comment documents — `waitpid`, `Pipe::backing`,
28+
`Virtio::submit`, and the three test binaries' module docs.
29+
30+
**Exit**: `git grep -w -E
31+
'SYS_WAITPID|SYS_CONNECT|SYS_AUDIO_SUBMIT|SYS_PIPE_OPEN|SYS_SOCKET_CREATE|SYS_LISTEN|SYS_RELEASE_SHARED'
32+
-- kernel userland tests` finds nothing.

‎issues/design-debt/the-abi-still-keeps-retired-syscall-numbers.md‎

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
status: open
3+
kind: defect
4+
opened: 2026-10-01
5+
---
6+
7+
# The window protocol keeps a retired message type
8+
9+
A deleted syscall, `SYS_DEBUG` action or inbox op is simply deleted, and its
10+
number is free. The window protocol still carries one retired type and refuses
11+
it by name:
12+
13+
- `userland/toyos-window/src/lib.rs`: `MSG_RETIRED_CLIPBOARD_SET_SHM = 10`;
14+
- `userland/compositor/src/client.rs`: `DropReason::Retired` and its `why`;
15+
- `userland/compositor/src/session.rs`: `Session::dispatch`'s arm for it.
16+
17+
Deleting the type makes a frame of 10 an unknown type, which `Session::dispatch`
18+
reads and drops without a word
19+
(`issues/isolation/the-compositor-ignores-a-message-it-does-not-know.md`). That
20+
issue lands first or with this one.
21+
22+
Owner: `Session::dispatch` in `userland/compositor/src/session.rs`.
23+
24+
**Exit**: `git grep -i retired userland/toyos-window userland/compositor` finds
25+
nothing, and a frame of type 10 drops its client with `DropReason::OutOfProtocol`.

‎issues/diagnostics/no-cyclictest.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ the privilege: a `SysCap` carrying `Rights::RT`, granted by a `system.toml` row
2121
and not in the scheduler. The gate this file was opened against is gone —
2222
`SYS_SET_RT_PRIORITY` (96) demanded a `VirtioSound` or `HdaAudio` device claim,
2323
so a latency tool could only reach the band by taking the sound card away from
24-
soundd and measuring a different machine. Number 96 is retired, and
25-
`toyos-abi/src/syscall.rs` says why: "a claim is not a privilege".
24+
soundd and measuring a different machine.
2625

2726
**What exists is not a substitute, and each instrument fails differently.**
2827
soundd's `max_wake_lat_ns` (`toyos-mixer/src/stats.rs`, printed by

‎issues/diagnostics/the-kernel-keeps-nothing-it-enumerates.md‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,6 @@ On top of retention, in dependency order:
4343
One residual is nearly free: a log-follow tool is a manifest row and about 30
4444
lines, because `LogTail` already exists in the SDK.
4545

46-
**Syscall numbers: the three this work once reserved are all taken, and the
47-
obvious fix is wrong too.** 97 and 98 are the device register read/write pair,
48-
99 is the endowments call. Re-allocating "from 128 up" breaks a compile-time
49-
assert, because 128 is the syscall-profile bin count and 127 is its overflow
50-
bucket. **The first clean numbers are 116, 117, 118** — 113 and 115 are held
51-
reservations, 114 is spent on log reading, and 96 and 107 are retired and never
52-
reused.
53-
5446
The log half of this work landed differently and better, and the difference is
5547
worth knowing before anything is rebuilt on the old design: reading is
5648
record-shaped rather than byte-shaped, it is authority (`Rights::LOG` on a

‎issues/isolation/the-supervisor-is-host-tested-and-owns-the-stop.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ nothing.
1616
1. **The rename**, one mechanical PR, first after #536. Before stage 1 is
1717
briefed, the exit's search below runs once over the `rust/` fork's delta as
1818
well as the superproject, so its hits are known going in. It touches `toyos/src`,
19-
`toyos-abi/src`, `userland/libc/src` and the `rust/` fork's delta, so it is
20-
briefed as an ABI brief, and its `CLAUDE.md` edits are placed in the same PR
19+
`toyos-abi/src`, `userland/libc/src` and the `rust/` fork's delta, and its
20+
`CLAUDE.md` edits are placed in the same PR
2121
by an agent briefed for them. Issue slugs carrying an old name are renamed
2222
with every citation.
2323

‎issues/kernel/sys-clock-realtime-is-now-a-format-of-sys-clock-epoch.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ into `h:m:s` (`toyos_abi::syscall::clock_realtime`), which every caller today
1212
could derive from `clock_epoch()` instead, with no information
1313
`SYS_CLOCK_REALTIME` carries that `SYS_CLOCK_EPOCH` does not.
1414

15-
Exit condition: `SYS_CLOCK_REALTIME`'s number (42) is retired and never
16-
reused, its kernel handler and `toyos_abi::syscall::clock_realtime` are
15+
Exit condition: `SYS_CLOCK_REALTIME`, its kernel handler and `toyos_abi::syscall::clock_realtime` are
1716
deleted, `toyos::system::clock_realtime` and both its callers
1817
(`userland/compositor/src/render.rs`,
1918
`tests/toyos-rust-tests/src/bin/wall_clock_now.rs`) move to `clock_epoch`, all

‎issues/kernel/sys-debug-actions-and-two-loader-words-that-nothing-calls.md‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ opened: 2026-10-01
88

99
The guest suite's first cut
1010
(`issues/build/the-guest-suite-runs-only-what-no-cheaper-tier-reaches.md`) deleted the only
11-
callers of nine `SYS_DEBUG` actions and the loader's reading of two boot words, and left their
11+
callers of eight `SYS_DEBUG` actions and the loader's reading of two boot words, and left their
1212
names in `toyos-abi/src`, because a deletion there is an ABI change and that pull request was not
1313
one. Each kernel arm still answers its action. `git grep -w <name> -- tests userland toyos src`
1414
finds no caller of:
@@ -18,14 +18,16 @@ finds no caller of:
1818
`syscall_fault_halts` and `heap_over_ceiling_halts` and stage C's `idle_stack_guard`;
1919
- `HEAP_AT_CEILING` (5), `HEAP_AT_CEILING_PAGE_ALIGNED` (7) and `LOWER_SYSINFO_BOUND` (19),
2020
`heap_ceiling`'s, for stage C's `heap_ceiling_bounds`;
21-
- `LOCK_ACROSS_SWITCH` (2), `test_panic_child`'s, and `LOG_PATTERNED` (21), test-runner's
22-
`log-gate` and `log-storm`. Their stage C items are a type (`lock_across_switch_halts`) and
23-
a host test (`log_conservation_smp2`), and neither calls `SYS_DEBUG`, so no stage brings a
24-
caller back;
21+
- `LOCK_ACROSS_SWITCH` (2), `test_panic_child`'s. Its stage C item is a type
22+
(`lock_across_switch_halts`), which calls no `SYS_DEBUG`, so no stage brings a caller back;
2523
- `boot::WRITE_NO_LAYOUT_PARAM` and `boot::WITHHOLD_ROOT_PARAM`, for stage A's
2624
`kernel_args_layout_refused` and `root_withheld_refused`.
2725

26+
`LOG_PATTERNED` (21) has one caller, `panic_halts_first`, which wants a record and reads none of
27+
the pattern `kernel/src/log/storm.rs` writes into it: the checksum and payload had test-runner's
28+
`log-gate` and `log-storm` as their readers, and stage C's `log_conservation_smp2` is a host test.
29+
2830
Owner: the orchestrator.
2931

3032
**Exit**: for each name, `git grep -w` finds a caller again, its stage's row, or an ABI change
31-
retires the name with its kernel arm and never reuses its number.
33+
deletes the name with its kernel arm; and `storm.rs`'s pattern has a reader or is deleted.

‎issues/kernel/the-capability-end-state-is-twelve-answers.md‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,7 @@ no replace", and a narrower one is a *new* object built from an existing one
295295
(`4a98107f^:kernel/src/arch/syscall.rs:1861`); `SYS_NAMESPACE_BUILD` demands
296296
`Rights::TRANSFER` on every added connector and resolves kept names against the
297297
base before installing anything (`:1754`). A process with no `svc` endowment
298-
resolves no name at all, and there is no registry to fall back to: 85
299-
`SYS_LISTEN` and 87 `SYS_CONNECT` are retired numbers
300-
(`4a98107f^:kernel/src/arch/syscall.rs:77`, `:78`). The **filesystem** path space is the
298+
resolves no name at all, and there is no registry to fall back to. The **filesystem** path space is the
301299
other thing the word could mean, and it is ambient process state
302300
(`4a98107f^:kernel/src/arch/syscall.rs:1234`) — questions 2 and 5 hold that half.
303301

0 commit comments

Comments
 (0)