B6 opening: T-022 security review + ADR-0037 + T-023 (EL0 entry context)#37
Conversation
Standalone, time-separated (2026-05-31) security pass over the T-022 / ADR-0033 high-half kernel migration, discharging the "awaiting explicit security review" flag current.md carried for UNSAFE-2026-0031. Verdict: Approve — eight axes pass (cryptography N/A), no live finding, no fix required. The migration is a structural kernel/user isolation *strengthening*: the kernel becomes absent from the TTBR0_EL1 regime an EL0 task runs on (removing the Meltdown substrate, replacing a standing per-descriptor AP invariant with structural absence). UNSAFE-2026-0031 + the 0022/0023/0024 T-022 Amendments are policy-conformant and second-reviewer-signed; the migration is smoke-verified fault-clean. The review-round-3 hardenings (fail-fast assert! range guards + regime-correct panic-handler UART alias) are verified sound and cannot misfire in v1 (incl. the no-double-panic property on the panic path). Forward-flagged (non-blocking, pre-B6): the three T-021 carry-forward gates (gate #1 — per-task console_write window + per-page user-VA->kernel-VA translation — is the single most important pre-B6 gate) and ADR-0034 (kernel-image section W^X; privileged-side gap, EL0-unreachable). Refs: T-022, ADR-0033 Security-Review: @cemililik (+ Claude Opus 4.8 (1M context) agent) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sibling ADR to ADR-0033 (which scoped itself to the migration and named the EL0 context a separate B6 task). Settles how an EL0 task's first entry is expressed and how it integrates with the cooperative scheduler. Decision (Option 1): reuse the existing Aarch64TaskContext + a one-shot enter_el0 ERET trampoline; carry (user_entry, user_sp) in the x19/x20 callee-saved slots the cooperative switch already restores; lr = enter_el0, sp = kernel stack. SP_EL1 (gate #2) is closed by construction — the task enters EL0 from its own kernel context, so a later +0x400 trap lands on that kernel stack. D2 settled: neither add EL0 fields to the kernel-object Task NOR a separate TaskContext struct — the 168-byte Aarch64TaskContext layout (and the security-critical context_switch_asm offsets) stay UNCHANGED, the exact drift the T-022 security review flagged. v1 simplification: SPSR_EL1 = 0x3C0 (EL0t, DAIF masked — cooperative, no preemption). Opens T-023 (Draft) in the same commit per ADR-0025 §Rule 1. Introduces UNSAFE-2026-0032 (the enter_el0 asm; security-sensitive → second-reviewer). Refs: ADR-0037, T-023 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Careful re-read (write-adr §10) passed in a separate commit from Propose: forward-references grounded (T-023 exists; downstream consumers deliberately absent as consumers-not-dependencies, per ADR-0033's pattern), dependency chain complete, negative consequences carry real mitigations, the §Simulation table walks the EL0 first-entry + trap state machine. Refs: ADR-0037 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…trampoline + per-task SP_EL1) Implements ADR-0037 (the B6 EL0 entry-context decision) — the dormant mechanism a userspace task needs to drop to EL0 on first dispatch. Closes T-021 carry-forward gate #2 (SP_EL1). No runnable EL0 task yet (that is the B6 wire-up, after gate #1 / gate #3); the mechanism is dormant and the QEMU trace is byte-stable. What lands: - HAL: `ContextSwitch::init_user_context(ctx, user_entry, user_sp, kernel_stack_top)` — additive sibling of `init_context`; its `# Safety` states the EL0-trap kernel-stack size contract (must hold the ~272-byte trap frame + handler call tree per +0x400, stronger than init_context's). - BSP: `QemuVirtCpu::init_user_context` seeds the *existing* Aarch64TaskContext (x19=user_entry, x20=user_sp, lr=enter_el0, sp=kernel_stack_top) — no struct/layout change, so context_switch_asm offsets are untouched (D2) — plus the `enter_el0` `#[unsafe(naked)]` ERET trampoline. - Scheduler: `Scheduler::add_user_task` (mirrors add_task, calls init_user_context; debug_asserts kernel_stack_top non-null + 16-aligned — gate #2 belt-and-braces). - test-hal: FakeContextSwitch::init_user_context + FakeTaskContext {is_user,user_sp}; host tests for the test-hal recorder and the scheduler route. All four ContextSwitch implementors updated (BSP + test-hal + scheduler's FakeCpu/ResetQueuesCpu). - Audit: new UNSAFE-2026-0032 (the enter_el0 ERET asm; second-reviewer-flagged). 2026-05-31 review-round (1 HIGH + 3 Medium + 4 nits) folded in BEFORE this commit: - HIGH — enter_el0 now SCRUBS the register file (x0–x30 + v0–v31) before ERET. The cooperative switch restores only callee-saved regs, so without the scrub the first EL0 instruction would observe kernel pointers/state in x0/x1/x8 (context ptrs / kernel stack), x30 (kernel code addr), and the caller-saved SIMD — a disclosure orthogonal to ADR-0033's AP/UXN memory isolation. Recorded as a load-bearing invariant (UNSAFE-2026-0032) and in ADR-0037 §Revision notes (CLAUDE.md #1). - SPSR_EL1 written via the register form (mov x8,#0x3c0; msr spsr_el1,x8) — the immediate MSR form is PSTATE-fields-only. - gate #2 reconciled (by-construction + the debug_assert); EL0-trap stack-size contract documented; test-scope claim narrowed (the host test pins the scheduler route via the fake — the real QemuVirtCpu slot write + the scrub are audit + kernel-build verified, the BSP being bare-metal). Docs synced: ADR-0037 §Revision notes (rider, append-only per ADR-0025 §Rule 2), T-023 (AC + review-history + row-to-verification mapping), hal.md + scheduler.md (ContextSwitch surface gains init_user_context / add_user_task), current.md (B6-opening banner + active-task/working-branch). Gates green: cargo fmt; host + kernel clippy -D warnings; 342 host tests (+2: test-hal init_user_context recorder, scheduler add_user_task route); kernel build (the 67-instruction scrub asm assembles); QEMU smoke byte-stable + fault-clean (mechanism dormant); cargo +nightly miri test --workspace --exclude tyrne-bsp-qemu-virt clean (0 UB). Security-relevant (the EL1→EL0 first-entry trust-boundary primitive); the ADR + task design review-round is folded in, the formal code security pass on UNSAFE-2026-0032 remains a DoD item before a real EL0 task is wired. Refs: T-023, ADR-0037, UNSAFE-2026-0032 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sserts, user_sp + AS-active guards
Folds in the 2026-05-31 second review-round against the committed
implementation (verdict: Approve-with-nits). 2 Low + 4 nits, all verified
against the code and addressed.
- Low-1 — enter_el0's scrub omitted the FP-control/status + EL0 thread-ID
register classes. It zeroed x0–x30 + v0–v31 but NOT FPCR/FPSR/TPIDR_EL0/
TPIDRRO_EL0 — all EL0-readable, with architecturally-UNKNOWN reset values on
real HW (Pi 4), so "clean, defined register file" was over-claimed off-QEMU
(FPCR governs EL0 rounding/FZ/default-NaN; Linux zeroes FPCR/FPSR on exec).
enter_el0 now also `msr {fpcr,fpsr,tpidr_el0,tpidrro_el0}, xzr`. No current
secret leak (kernel does no FP arithmetic, never writes TPIDR), but the EL0
environment is now defined on real HW, not just QEMU's zeroed reset.
- Low-2 — the implicit x19/x20/lr/sp hand-off was pinned only by
size_of == 168; a layout-preserving field reorder (e.g. fp/lr swap) would
silently corrupt both context_switch_asm and the enter_el0 hand-off. Added
offset_of! asserts for all five offsets (0/80/88/96/104) — hardens the
pre-existing context_switch_asm coupling too.
- Nit — add_user_task now debug_asserts user_sp 16-byte alignment (it becomes
SP_EL0; SCTLR_EL1.SA0 faults a misaligned EL0 stack), symmetric with the
kernel-stack assert.
- Nit — the AS-must-be-active obligation (TTBR0 installed + EPD0 cleared at
first dispatch) is now stated on the caller-facing # Safety of both
init_user_context and add_user_task (it previously lived only on enter_el0's
doc, which the future task_create_from_image author would not read).
- Nit (process honesty) — the review-round-1 rider shipped WITH bbc42e8, after
ADR-0037's Accept (546febc): the careful-re-read missed the scrub HIGH;
recorded in ADR-0037 §Revision notes per ADR-0025 §Rule 2.
- Nit — "67-instruction scrub" wording dropped (it is 63 register-zeros + 4
special-register writes); docs reworded.
Docs synced: UNSAFE-2026-0032 (scrub scope), ADR-0037 §Revision notes (second
rider), T-023 (AC + review-history), hal.md, current.md.
Gates green: cargo fmt; host + kernel clippy -D warnings; 342 host tests;
kernel build (offset_of! asserts + the new MSRs assemble); QEMU smoke
byte-stable + fault-clean (mechanism still dormant); cargo +nightly miri test
--workspace --exclude tyrne-bsp-qemu-virt clean (0 UB).
Refs: T-023, ADR-0037, UNSAFE-2026-0032
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oc drift, T-023 status/ACs A multi-agent adversarial review of the whole T-023 arc (b6549d7..HEAD; 5 lenses × per-finding skeptic verification) found NO code/security/correctness/ asm defect — the register scrub (incl FPCR/FPSR/TPIDR), the offset_of! asserts, the SPSR register form, the dormancy + gate ordering, all four ContextSwitch implementors, and the host tests were verified correct. The only confirmed findings were three doc-only consistency defects, all fixed: - The T-022 security review (2026-05-31) cited ADR-0033's Accept as `db392c1`, which does not exist (transposed digit) — corrected to `db892c1`. - `FakeContextSwitch::init_count()`'s rustdoc said "init_context calls" but the shared counter is now also incremented by `init_user_context`; doc broadened to match (mirrors the already-updated `FakeTaskContext.initialized` field doc). - T-023 was still `Status: Draft` with all nine ACs unchecked despite being implemented + gates-green; moved to "In Review (… awaiting explicit security review …)" per the T-022 house convention and checked the nine satisfied ACs. Gates re-confirmed: cargo fmt, host clippy -D warnings, 342 host tests (kernel binary unchanged → the prior byte-stable QEMU smoke + Miri-0-UB still hold). Refs: T-023, ADR-0037 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reviewer's GuideImplements the EL0 first-entry mechanism for B6 by extending the HAL context-switch trait with a userspace initializer, adding a one-shot AArch64 Sequence diagram for EL0 first-entry via enter_el0 trampolinesequenceDiagram
participant Scheduler
participant QemuVirtCpu
participant context_switch_asm
participant enter_el0
participant EL0_task
Scheduler->>QemuVirtCpu: init_user_context(ctx, user_entry, user_sp, kernel_stack_top)
Note right of QemuVirtCpu: Seeds Aarch64TaskContext
QemuVirtCpu-->>Scheduler: ctx.x19_x28[0..1], ctx.lr, ctx.sp set
Scheduler->>QemuVirtCpu: context_switch(current_ctx, next_ctx)
QemuVirtCpu->>context_switch_asm: context_switch_asm(current_ctx, next_ctx)
context_switch_asm-->>enter_el0: ret (x19=user_entry, x20=user_sp, sp=kernel_stack_top)
enter_el0->>enter_el0: msr sp_el0, x20
enter_el0->>enter_el0: msr elr_el1, x19
enter_el0->>enter_el0: msr spsr_el1, x8 (0x3c0)
enter_el0->>enter_el0: [scrub x0-x30, v0-v31, FPCR/FPSR/TPIDR]
enter_el0-->>EL0_task: eret to user_entry (SP=SP_EL0)
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughImplements EL0 first-entry via a new HAL method ChangesEL0 Entry Context Implementation
Documentation, Planning, and Audit
Sequence DiagramsequenceDiagram
participant Scheduler
participant CPU as CPU/ContextSwitch
participant TaskContext
participant ContextSwitch as context_switch_asm
participant Trampoline as enter_el0
participant EL0 as EL0 User Task
Scheduler->>CPU: init_user_context(entry, user_sp, kernel_stack_top)
CPU->>TaskContext: seed x19=entry, x20=user_sp, lr=enter_el0, sp=kernel_stack_top
Scheduler->>Scheduler: enqueue task ready
Scheduler->>ContextSwitch: restore from TaskContext on dispatch
ContextSwitch->>Trampoline: RET (lr=enter_el0)
Trampoline->>Trampoline: MSR SP_EL0, user_sp (from x20)
Trampoline->>Trampoline: MSR ELR_EL1, entry (from x19)
Trampoline->>Trampoline: MSR SPSR_EL1, 0x3C0 (EL0t, DAIF masked)
Trampoline->>Trampoline: zero x0-x30, v0-v31, FPCR, FPSR, TPIDR_EL0
Trampoline->>EL0: ERET
EL0->>EL0: execute user code
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces the foundational EL0 (userspace) entry context mechanism, adding the init_user_context HAL trait method, the enter_el0 naked assembly trampoline, and the Scheduler::add_user_task method. A critical security issue was identified in the enter_el0 trampoline where MSR instructions use xzr to zero the FP and thread-ID registers. In A64, xzr is encoded as 31 which represents SP for MSR instructions, potentially leaking the kernel stack pointer to userspace. It is recommended to use a zeroed general-purpose register like x0 instead.
| "msr fpcr, xzr", | ||
| "msr fpsr, xzr", | ||
| "msr tpidr_el0, xzr", | ||
| "msr tpidrro_el0, xzr", |
There was a problem hiding this comment.
In the A64 instruction set, the MSR (register) instruction does not support the zero register (XZR) as a source operand. The Rt register field value of 31 represents the stack pointer (SP) for MSR and MRS instructions.\n\nDepending on the toolchain/assembler version, using xzr here will either:\n1. Cause a compilation/assembly failure (e.g., LLVM/Clang or GCC gas rejecting xzr as an invalid operand for MSR).\n2. Or, if accepted, assemble as msr <reg>, sp, which writes the active kernel stack pointer (SP_EL1) into fpcr, fpsr, tpidr_el0, and tpidrro_el0. Since tpidr_el0 and tpidrro_el0 are readable by EL0 (userspace), this creates a critical security vulnerability by leaking the kernel stack pointer directly to userspace, defeating stack protection and KASLR.\n\nTo ensure correctness, portability, and security, use a general-purpose register that has already been zeroed (such as x0, which is zeroed on line 491) instead of xzr.
| "msr fpcr, xzr", | |
| "msr fpsr, xzr", | |
| "msr tpidr_el0, xzr", | |
| "msr tpidrro_el0, xzr", | |
| "msr fpcr, x0",\n "msr fpsr, x0",\n "msr tpidr_el0, x0",\n "msr tpidrro_el0, x0", |
There was a problem hiding this comment.
Verified against the build + the ISA, and respectfully this does not apply — no change made.
For MSR/MRS, Rt = 31 is XZR, not SP: MSR (register) reads its source through the X[t] (zero-register) accessor, so msr <sysreg>, xzr writes 0. The "Rt = 31 ⇒ SP" rule applies to load/store base registers and the SP-form of arithmetic — not to MSR/MRS.
Confirmed three independent ways:
- The assembler accepts it.
cargo kernel-buildassemblesmsr {fpcr,fpsr,tpidr_el0,tpidrro_el0}, xzrwith no error — so the "rejected operand" failure mode does not occur. - It encodes as XZR, not SP. The kernel already ships
msr ttbr0_el1, xzr(the TTBR0-free inkernel_main_high);rust-objdumpdisassembles it asmsr TTBR0_EL1, xzr(d518201f,Rt = 31) — renderedxzr, notsp. The four FP/thread-ID writes here use the identical MSR-register source encoding. - Behaviourally proven. That
msr ttbr0_el1, xzris smoke-clean:TTBR0_EL1becomes 0 (correctly freeing the low half). IfRt = 31meantSP,TTBR0would hold a stack pointer and the kernel would translation-fault on the next low-half access — it does not (-d int,unimpshows zero Translation/Permission faults).
So these instructions zero FPCR/FPSR/TPIDR_EL0/TPIDRRO_EL0 (the intended register scrub) with no SP leak. Rationale also recorded in commit 9b36967.
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The
enter_el0naked_asm block manually zeros all GPRs and SIMD registers one by one; consider factoring this into a small local macro or.irp-style pattern so future changes don’t accidentally miss a register or introduce inconsistencies while still keeping the scrub logic explicit and auditable. ContextSwitch::init_user_contextis a new required unsafe method on the trait; you might want to provide a default implementation (e.g.unimplemented!()or delegating toinit_context) so new BSPs or test HALs fail loudly rather than silently omitting EL0 bring-up when they add a ContextSwitch impl and forget to wire this method.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `enter_el0` naked_asm block manually zeros all GPRs and SIMD registers one by one; consider factoring this into a small local macro or `.irp`-style pattern so future changes don’t accidentally miss a register or introduce inconsistencies while still keeping the scrub logic explicit and auditable.
- `ContextSwitch::init_user_context` is a new required unsafe method on the trait; you might want to provide a default implementation (e.g. `unimplemented!()` or delegating to `init_context`) so new BSPs or test HALs fail loudly rather than silently omitting EL0 bring-up when they add a ContextSwitch impl and forget to wire this method.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test-hal/src/context_switch.rs`:
- Around line 189-202: When re-seeding a reused TaskContext via the kernel path,
clear any leftover user-path markers so stale values from init_user_context
don't persist: update init_context to explicitly set ctx.is_user = false and
ctx.user_sp = 0 (and if applicable clear any user-specific entry_addr/user-only
fields) while still setting ctx.initialized, ctx.entry_addr/stack_top for the
kernel, and preserving the locked().init_count increment; this ensures
init_context fully overwrites any prior user state left by init_user_context.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f6060822-2713-4e9b-9a85-9b128e760976
📒 Files selected for processing (12)
bsp-qemu-virt/src/cpu.rsdocs/analysis/reviews/security-reviews/2026-05-31-T-022-high-half-migration.mddocs/analysis/tasks/phase-b/T-023-el0-entry-context.mddocs/architecture/hal.mddocs/architecture/scheduler.mddocs/audits/unsafe-log.mddocs/decisions/0037-el0-entry-context.mddocs/decisions/README.mddocs/roadmap/current.mdhal/src/context_switch.rskernel/src/sched/mod.rstest-hal/src/context_switch.rs
…markers on slot reuse
FakeContextSwitch::init_context (the kernel path) seeded initialized/
entry_addr/stack_top but left is_user / user_sp untouched, so a context slot
re-seeded user-task -> kernel-task would report stale is_user=true / a stale
user_sp. init_context now fully re-seeds a kernel context: clears is_user and
user_sp. Adds a regression test (init_context_clears_prior_user_markers_on_reuse).
Test-double-only correctness; no runtime/kernel effect.
Skipped (with reason) from the same review:
- "msr {fpcr,fpsr,tpidr_el0,tpidrro_el0}, xzr leaks SP" — INVALID. For MSR/MRS,
Rt=31 is XZR (the X[]/ZR accessor), not SP (the 31=SP rule is for load/store
base + SP-form arithmetic). Verified: kernel-build assembles these cleanly,
and the shipped `msr ttbr0_el1, xzr` disassembles as `msr TTBR0_EL1, xzr`
(d518201f) and is smoke-clean (TTBR0 -> 0, would fault if SP). No change.
- "factor the enter_el0 scrub into a .irp/macro" — SKIPPED. The explicit
per-register form is deliberately maximally auditable for a security-critical
scrub (every scrubbed register visible); the register set is fixed; no defect.
- "give init_user_context a default impl (unimplemented!/delegate)" — SKIPPED.
A required trait method already fails loudest (compile error) if an
implementor omits it; unimplemented! would defer that to a runtime panic
(against the kernel's panic-free discipline + kernel-clippy denies panic),
and delegating to init_context would silently produce a broken EL0 entry.
Gates: cargo fmt; host clippy -D warnings; 343 host tests (+1); Miri 0 UB
(kernel binary unchanged -> prior byte-stable QEMU smoke holds).
Refs: T-023
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Responding to @sourcery-ai's two high-level points — both considered and intentionally not actioned (rationale also recorded in commit 1. Factor the 2. Give (For completeness: @coderabbitai's inline comment on |
|
Tip For best results, initiate chat on the files or code changes.
On the explicit scrub: Agreed. For a one-time, security-auditable register wipe of a fixed ISA register set, the verbosity is the feature. A On the required trait method (no default): The compile-error-vs-silent-wrong-EL1-entry argument is exactly right. A default that delegates to Glad the slot-reuse fix ( ✏️ Learnings added
|
Opens Milestone B6 (first userspace "hello") on the merged high-half regime. Lands the gating T-022 security review, the EL0 entry-context decision (ADR-0037), and its dormant implementation (T-023) — closing T-021 carry-forward gate #2. No runnable EL0 task yet; the mechanism is dormant (
syscall_entrystays unreachable from EL0 whileEPD0 = 1), so the QEMU trace is byte-stable.Commits
9a51b7300d342e/546febcbbc42e8ContextSwitch::init_user_context+ the BSPenter_el0ERETtrampoline +Scheduler::add_user_task(+ review-round-1 findings)771ebd1FPCR/FPSR/TPIDRscrub,offset_of!layout asserts,user_sp+ AS-active guards12095c6Design (ADR-0037)
A userspace task reuses the cooperative context switch.
init_user_contextseeds the existingAarch64TaskContext(x19=user_entry,x20=user_sp,lr=enter_el0,sp=kernel_stack_top) — no struct/layout change (D2), socontext_switch_asm's offsets are untouched. The unchanged switch restores those andrets intoenter_el0, which setsSP_EL0/ELR_EL1/SPSR_EL1(EL0t + DAIF-masked), scrubs the EL0-visible register file (x0–x30+v0–v31+FPCR/FPSR/TPIDR_EL0/TPIDRRO_EL0), andERETs. Gate #2 (SP_EL1) is closed by construction — the task enters EL0 from its own kernel context, so a later+0x400trap lands on that kernel stack. NewUNSAFE-2026-0032(second-reviewer-flagged).Security
The
enter_el0register scrub is load-bearing: the cooperative switch restores only callee-saved regs, so without it the first EL0 instruction would read kernel pointers (x0/x1/x8), a kernel code address (x30), and caller-saved SIMD — a disclosure orthogonal to ADR-0033'sAP/UXNmemory isolation. The scrub also zeroesFPCR/FPSR/TPIDR_EL0/TPIDRRO_EL0(UNKNOWN-reset on real HW, e.g. Pi 4) for a defined EL0 environment.Review
Three review passes total. A final multi-agent adversarial review (5 lenses × per-finding skeptic verification) found no code/security/correctness/asm defect — the scrub, the
offset_of!asserts, the SPSR register form, the dormancy/gate-ordering, all fourContextSwitchimplementors, and the host tests were verified correct. The only findings were three doc-only consistency fixes (already applied in12095c6). T-023's own formal code security review (UNSAFE-2026-0032) remains a DoD item before a real EL0 task is wired in B6.Gates
cargo fmt· host + kernelclippy -D warnings· 342 host tests (+2) · kernel build (the scrub asm +offset_of!asserts assemble) · QEMU smoke byte-stable + fault-clean (mechanism dormant) ·cargo +nightly miri test --workspace --exclude tyrne-bsp-qemu-virt0 UB.Not in scope (next B6 threads)
task_create_from_image→ the security-critical gate #1 (per-task user-VA→kernel-VA translation) + gate #3 →tyrne-user+userland/hello+ build pipeline → wire-up + EL0+0x400smoke → closure (= Phase B retrospective).🤖 Generated with Claude Code
Summary by Sourcery
Introduce a dormant EL0 entry mechanism that reuses the existing Aarch64 cooperative context switch, including a new enter_el0 trampoline and scheduler API for seeding userspace tasks, alongside updated safety assertions and documentation for ADR-0037 and the T-022 security review.
New Features:
Enhancements:
Documentation:
Tests:
Summary by CodeRabbit
New Features
Documentation
Tests