Commit 06eddd8
reaper: defer terminating task's active page-table root + kernel stack (ADR-034 Phase A)
Fixes the confirmed clean-exit triple-fault on x86_64 + riscv64: a dying
task freed the page-table root still loaded in its own CR3/satp before it
yielded, and zero-on-free (318c1cd) made that fatal — freeing the active
PML4 zeroes the kernel half and the next instruction triple-faults. The
self-referential set a task cannot free from its own running context — the
page-table root + intermediates and the kernel stack — is now captured by
value and freed later by a per-CPU reaper running in a clean context.
What:
- New src/reaper.rs: `ReclaimItem` { root_phys, kstack_top } + a bounded
per-CPU `ReclaimQueue` (`RECLAIM_QUEUE_CAPACITY` = MAX_TASKS, SCAFFOLDING-
tagged: one slot per task slot makes overflow structurally impossible,
ADR-034 §5) + `drain_local()`, which pops items and frees the root via
`reclaim_process_page_tables` then the kernel stack via `dealloc`.
- src/lib.rs: `pub mod reaper`; `PER_CPU_RECLAIM_QUEUE`
(`[IrqSpinlock<ReclaimQueue>; MAX_CPUS]`) + `local_reclaim_queue()` for
all three arches. IrqSpinlock (not plain Spinlock) because the pusher is
a task in the Terminated-but-still-running state; isolated "Additional
lock domain", never nested with a hierarchy lock.
- src/microkernel/main.rs: `reaper::drain_local()` wired into all five
per-CPU idle loops (BSP x86/aarch64 microkernel_loop, BSP riscv, and the
three AP loops) — normal context, interrupts enabled, SCHEDULER not held.
- src/process.rs: `destroy_process` no longer frees page tables inline; it
returns `Option<u64>` (the root to defer), `#[must_use]`. VMA + heap +
generation bump stay inline, unchanged. Stale-id test strengthened to
assert the deferral return.
- src/syscalls/dispatcher.rs (`handle_exit`): captures the kernel stack +
transition-winner under SCHEDULER, captures the deferred root from
destroy_process, then enqueues { root, kstack } under the per-CPU queue
lock alone (every hierarchy lock released) immediately before the terminal
yield. Enqueue-once is gated on winning the Running->Terminated
transition; a full queue degrades to a logged bounded leak, never a panic
or block. Safe to enqueue here: purge_task cleared current_task, so the
timer ISR takes its no-switch path and the dying task is never
involuntarily switched away before the item is durable.
- src/memory/paging.rs (x86) + src/memory/mod.rs (non-x86): release-build
active-root guard at the top of `reclaim_process_page_tables` — reads
CR3 / satp / TTBR0 and refuses (frees nothing, audits, debug-asserts) if
asked to free the active root. Defense-in-depth: post-Phase-A the reaper
only ever frees roots the owner has yielded off, so a hit means a
regression reintroduced the self-free.
- src/audit/mod.rs: `AuditEventKind::ReapWouldFreeActiveRoot = 21` +
builder — the runtime witness for the guard above. Purely additive (no
exhaustive match over AuditEventKind exists outside the audit module).
- src/loader/mod.rs: `KERNEL_STACK_SIZE` made `pub` (the reaper rebuilds
the exact dealloc Layout); fixed a stale SAFETY comment (8192 -> 32768).
- docs/ASSUMPTIONS.md: `RECLAIM_QUEUE_CAPACITY` SCAFFOLDING row.
- tools/check-*-baseline.txt: line-number resyncs for entries my edits
shifted + the descriptive "deferred" tokens inherent to a module about
deferred reclamation (same treatment as the ADR-029/031/033 tokens). No
new untagged bound and no new Convention-9 deferral. The two stale
boot_modules.rs assumptions entries are preserved (their cleanup remains
the separately-flagged Phase-0 item).
Why: ADR-034 (ratified 62c59ba). The active-root self-free is the
triple-fault Tier C boot-smoke surfaced; the kernel stack ("can't free the
stack you're running on") was a standing leak with the same root cause. One
mechanism closes both.
Out of scope:
- Task-slot leak (HV1): Phase B — TaskId generation + TaskExitRing +
WaitTask rewrite + H5 co-fix. The slot is intentionally not deferred here.
- The dedicated per-CPU reaper *task* vehicle: Phase A drains from the
existing idle loops, which is the exact normal-context the ADR requires;
building a ring-0 kernel-task trampoline now is new arch-specific unsafe
of the same triple-fault class we are fixing, for no Phase-A correctness
gain (overflow is structurally impossible; slots leak in Phase A anyway).
The v1-shape drain_local() is reused verbatim by any future vehicle;
promotion is deferred to ADR-034's latency trigger.
- STATUS.md (kernel-stack-leak known-issue resolution, subsystem-row sync):
flagged for separate application to respect the parallel-session boundary
and the index-isolation gate.
Verification:
- make check-all: x86_64 + aarch64 + riscv64 build cleanly.
- cargo test --lib: 892 passed, 0 failed.
- check-assumptions / check-deferrals / check-unsafe-coverage /
check-boot-panics: all pass (0 new). clippy: no new warnings, no
missing_safety_doc error.
- Boot before/after (x86_64, make run-quiet): the pre-fix tree HANGS at
`[FDE-MOUNT] ... skipping FDE unlock` (run-quiet exit 2) — fde-mount's
boot-time `sys::exit` frees the active PML4 and triple-faults. The
post-fix tree sails past that exact point to `CambiOS Shell v0.1`
(exit 0). Only difference between the trees is this change.
Staged files:
docs/ASSUMPTIONS.md
src/audit/mod.rs
src/lib.rs
src/loader/mod.rs
src/memory/mod.rs
src/memory/paging.rs
src/microkernel/main.rs
src/process.rs
src/reaper.rs
src/syscalls/dispatcher.rs
tools/check-assumptions-baseline.txt
tools/check-deferrals-baseline.txt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>1 parent 62c59ba commit 06eddd8
12 files changed
Lines changed: 479 additions & 49 deletions
File tree
- docs
- src
- audit
- loader
- memory
- microkernel
- syscalls
- tools
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
| 81 | + | |
81 | 82 | | |
82 | 83 | | |
83 | 84 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
103 | 113 | | |
104 | 114 | | |
105 | 115 | | |
| |||
643 | 653 | | |
644 | 654 | | |
645 | 655 | | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
646 | 680 | | |
647 | 681 | | |
648 | 682 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| |||
724 | 725 | | |
725 | 726 | | |
726 | 727 | | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
727 | 766 | | |
728 | 767 | | |
729 | 768 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
46 | 50 | | |
47 | 51 | | |
48 | 52 | | |
| |||
690 | 694 | | |
691 | 695 | | |
692 | 696 | | |
693 | | - | |
| 697 | + | |
694 | 698 | | |
695 | 699 | | |
696 | 700 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
443 | 443 | | |
444 | 444 | | |
445 | 445 | | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
446 | 475 | | |
447 | 476 | | |
448 | 477 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
292 | 292 | | |
293 | 293 | | |
294 | 294 | | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
295 | 324 | | |
296 | 325 | | |
297 | 326 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
907 | 907 | | |
908 | 908 | | |
909 | 909 | | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
910 | 913 | | |
911 | 914 | | |
912 | 915 | | |
| |||
1037 | 1040 | | |
1038 | 1041 | | |
1039 | 1042 | | |
| 1043 | + | |
| 1044 | + | |
1040 | 1045 | | |
1041 | 1046 | | |
1042 | 1047 | | |
| |||
2186 | 2191 | | |
2187 | 2192 | | |
2188 | 2193 | | |
| 2194 | + | |
| 2195 | + | |
2189 | 2196 | | |
2190 | 2197 | | |
2191 | 2198 | | |
| |||
2275 | 2282 | | |
2276 | 2283 | | |
2277 | 2284 | | |
| 2285 | + | |
| 2286 | + | |
2278 | 2287 | | |
2279 | 2288 | | |
2280 | 2289 | | |
| |||
2637 | 2646 | | |
2638 | 2647 | | |
2639 | 2648 | | |
| 2649 | + | |
| 2650 | + | |
| 2651 | + | |
| 2652 | + | |
| 2653 | + | |
| 2654 | + | |
2640 | 2655 | | |
2641 | 2656 | | |
2642 | 2657 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
992 | 992 | | |
993 | 993 | | |
994 | 994 | | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
995 | 1010 | | |
996 | 1011 | | |
997 | 1012 | | |
998 | 1013 | | |
999 | | - | |
| 1014 | + | |
1000 | 1015 | | |
1001 | 1016 | | |
1002 | | - | |
| 1017 | + | |
1003 | 1018 | | |
1004 | 1019 | | |
1005 | 1020 | | |
1006 | 1021 | | |
1007 | 1022 | | |
1008 | | - | |
| 1023 | + | |
1009 | 1024 | | |
1010 | 1025 | | |
1011 | 1026 | | |
1012 | 1027 | | |
1013 | | - | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
1014 | 1031 | | |
1015 | 1032 | | |
1016 | | - | |
1017 | | - | |
1018 | | - | |
1019 | | - | |
1020 | | - | |
1021 | | - | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
1022 | 1037 | | |
1023 | 1038 | | |
1024 | 1039 | | |
| |||
1027 | 1042 | | |
1028 | 1043 | | |
1029 | 1044 | | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
1030 | 1049 | | |
1031 | 1050 | | |
1032 | 1051 | | |
| |||
1522 | 1541 | | |
1523 | 1542 | | |
1524 | 1543 | | |
1525 | | - | |
| 1544 | + | |
| 1545 | + | |
1526 | 1546 | | |
1527 | | - | |
| 1547 | + | |
| 1548 | + | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
1528 | 1552 | | |
1529 | 1553 | | |
1530 | 1554 | | |
1531 | 1555 | | |
1532 | 1556 | | |
1533 | 1557 | | |
1534 | | - | |
| 1558 | + | |
| 1559 | + | |
1535 | 1560 | | |
1536 | | - | |
| 1561 | + | |
| 1562 | + | |
| 1563 | + | |
| 1564 | + | |
| 1565 | + | |
1537 | 1566 | | |
1538 | 1567 | | |
1539 | 1568 | | |
| |||
0 commit comments