feat(arch): exception vectors and a reporter that names the fault - #4
Merged
Conversation
The instrument the soft-float bug had to be diagnosed without. That bug β
an FP/SIMD trap vectoring through VBAR_EL1 = 0 into unmapped memory, one
instruction before the kernel's first console character β took an
instruction trace and three wrong hypotheses to find. With this table
installed it is one line:
[EXCEPTION] synchronous, current EL, SP_ELx (vector 4)
EC = 0x07 β FP/SIMD access trapped by CPACR_EL1.FPEN ...
boot.s installs the 2 KiB-aligned sixteen-entry table into VBAR_EL1 before
the first Rust instruction runs, so even the earliest fault is reported
rather than dying mute. Every entry routes to a common stub that forces
SPSel back to SP_ELx (so even the never-used SP_EL0 group lands on a real
stack), marshals ESR/ELR/FAR/SPSR, and calls a never-returning Rust
reporter that decodes the exception class into a sentence and halts.
Design decisions, for the reviewer:
- Terminal by design. Until there is a scheduler, every exception is a
report and a halt: recovery is policy, and there is nothing yet to
recover to. The vectors clobber registers freely and save no frame β
vectors.s documents that this discipline ends the day the timer IRQ
arrives and the IRQ entries grow a real save/restore path.
- The reporter prints line by line on the lock-free console, for the
same reason the panic handler does: when the machine is dying, half a
message is evidence and a lock is a hang.
- Decoded classes name causes, not numbers: EC 0x07 names CPACR_EL1.FPEN
outright; data aborts point at FAR. Classes the kernel cannot yet meet
report raw rather than guessing.
- The EL1 assumption is now load-bearing (VBAR_EL1, SPSel) and boot.s's
header says so explicitly: an explicit CurrentEL check and EL2 descent
are owed before real hardware or virtualization=on. QEMU virt without
that flag enters -kernel images at EL1, which is what the xtask
harness always uses.
Self-testing, not trusted: a provoke-exception feature (never on by
default) boots, greets, then executes brk #0; CI's boot job greps the
console for the decoded "BRK instruction" report on every pull request.
cargo xtask grows --features passthrough for exactly that. The ordinary
greeting path is asserted unchanged in the same job.
unsafe register (constitution Β§11.3) β all in the designated arch tree:
- arch/aarch64/mod.rs one new block: `brk #0` (feature-gated self-test)
- arch/x86_64/mod.rs one new block: `ud2` (same surface; unreachable
until the x86_64 boot path exists, documented)
- arch/aarch64/exception.rs `#[unsafe(no_mangle)]` attribute so
vectors.s can name the reporter
New assembly: vectors.s in full, and the four-instruction VBAR_EL1 install
in boot.s β per the header of boot.s, every instruction there should be
checked against the Arm ARM by the reviewer; the writing is delegated, the
understanding is not (Β§5.3).
Verified in the devcontainer: fmt, pins, spelling, markdown; clippy and
build for both Tier-1 targets in both feature states; xtask clippy and
tests; boot-test greeting; boot-test provoked fault decoding EC 0x3c at
vector 4.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Installs the AArch64 exception vector table (
VBAR_EL1, 2 KiB-aligned, sixteen entries) before the first Rust instruction, routing every exception to a reporter that decodesESR_EL1into a sentence and halts. The soft-float bug that cost an afternoon of instruction tracing becomes one console line β EC 0x07's decode namesCPACR_EL1.FPENoutright.Proven, not trusted: a
provoke-exceptionfeature boots, greets, then executesbrk #0, and the CI boot job greps for the decodedEC = 0x3c β BRK instructionreport on every PR. Local run shows exactly that at vector 4 (synchronous, current EL, SP_ELx).Which pillar does this serve?
None directly β this is kernel-doctrine infrastructure (Β§3: minimal, mechanism-only) and the debugging instrument for everything Β§10 Phase 1 still owes: scheduler, IPC, capabilities, MMU all get bring-up faults, and now those faults speak.
Borrow Ledger
Microkernel core / boot path β write ourselves, authored AI-first per amended Β§5.3, reviewed line by line by the maintainer. The table layout is architecturally dictated; the design decisions (terminal-by-design, SPSel forcing, EL1 assumption made explicit) are documented in
vectors.s,exception.rsand the commit message.unsaferegisterarch/aarch64/mod.rsβ one new block:brk #0in the feature-gated self-test, with SAFETY commentarch/x86_64/mod.rsβ one new block:ud2, same surface on the other Tier-1 target, unreachable until its boot path exists (documented)arch/aarch64/exception.rsβ#[unsafe(no_mangle)]attribute so the assembly can name the reportervectors.s(whole file),boot.s(four-instructionVBAR_EL1install) β please check these against the Arm ARM; this is the least forgiving code in the treeChecklist
-D warningsCHANGELOG.mdupdated under[Unreleased]unsaferegister above; all blocks in the designatedarch/**tree with// SAFETY:commentsπ€ Generated with Claude Code