Skip to content

Feature/bootloader hardening#162

Open
senseix21 wants to merge 124 commits into
mainfrom
feature/bootloader-hardening
Open

Feature/bootloader hardening#162
senseix21 wants to merge 124 commits into
mainfrom
feature/bootloader-hardening

Conversation

@senseix21
Copy link
Copy Markdown
Collaborator

This pull request introduces several new debug-only features to the project, primarily by adding new feature flags in Cargo.toml. Additionally, it makes minor improvements to the QEMU configuration in the Makefile to enhance the emulation environment. The changes are mostly focused on aiding kernel and heap debugging, as well as improving the development workflow for the desktop environment.

Debug and development features:

  • Added new debug-only feature flags in Cargo.toml:
    • nonos-trap-kstack-writer: Traps kernel writers that overwrite kernel memory in user-stack return slots, with additional diagnostics.
    • nonos-heap-debug: Logs heap canary/header mismatches at free to surface heap corruption.
    • nonos-cpuswitch-selftest: Runs a kernel context-switch self-test at boot.
    • nonos-desktop-lean: Spawns only the GUI core for a lean desktop environment, skipping network, apps, and market.

QEMU emulation improvements:

  • Enabled the virtual GPU (QEMU_GPU) by default in the QEMU invocation for nonos-mk-run-serial and removed the disable-modern=on option, improving graphical emulation. [1] [2]

senseix21 added 30 commits May 17, 2026 16:03
…ect of progressive/arith/entropy) — jpeg.rs [4c]
…er >4 GiB; fixes ExitBootServices #PF) — constants.rs
senseix21 added 26 commits May 23, 2026 13:17
allocate_user_stack mapped frames straight from frame_alloc
(phys::alloc(EMPTY) -- never zeroed) into the capsule's address space, so
a capsule's initial user stack inherited whatever the frame last held.
When a frame had previously backed a kernel stack, that's live kernel-VA
content (e.g. 0xffffff50.. VMAP kstack addresses); a capsule that returns
from _start pops the stale slot and jumps into the kernel half -> CPL=3
fault. Zero each frame via its directmap alias before mapping. Fixes the
info-leak and the kstack-VA-in-control-flow faults (verified: no more
0xffffff50.. rips on the full desktop; residual faults are app capsules'
own null-derefs/#GPs, unrelated).
Adds a free-quarantine ring (heap/types/quarantine.rs): freed user regions
are filled with a canonical-but-unmapped poison word (0x0000_5EED_5EED_5EED)
and held in a 1024-slot ring so reuse is delayed. A use-after-free *read*
of a poisoned pointer then faults as a #PF with cr2=...5EED.. (visible in
the trap dump); a stray *write* to freed memory is caught when the block is
evicted and re-scanned ([UAF-WRITE] logs the offset + the written word).
Gated by nonos-heap-debug; the production dealloc path is unchanged.

Empirical signal: with quarantine active, the intermittent teardown #GP
(~80% of runs without it) did not reproduce across the first runs, implying
the inbox-registry corruption is reuse/layout-related (a freed block reused
too eagerly), not a wild write to live memory.
The inbox registry (BTreeMap<String, Arc<Inbox>>) was guarded by a
spin::RwLock that does not mask interrupts. A timer tick during a
register/unregister could preempt the thread mid-BTreeMap-mutation; the
preemption path itself allocates (saving context into the
INTERRUPT_SAVED_CONTEXTS map), so the global allocator handed back a node
the in-progress mutation had just freed, and the resuming op then walked a
recycled/overwritten link -> non-canonical pointer -> #GP in remove_leaf_kv
on the next capsule teardown, wedging the kernel.

Disable interrupts across each registry tree mutation (acquire the write
lock first, then the interrupt guard, so a writer never disables interrupts
while spinning on a reader-held lock). The mutation now runs atomically and
no preemption can recycle its transient frees.

Diagnosis: a poison+quarantine allocator (nonos-heap-debug) showed the
corruption is reuse-sensitive -- a 1-slot reuse delay suppressed it across
all runs, and HEAP_ZERO_ON_FREE=true ruled out stale content -- isolating
it to immediate re-entrant reuse. Verified: 6/6 full-desktop boots clean
(teardown #GP gone) vs ~80% wedge before.
…phase 1)

Eager FXSAVE/FXRSTOR state moves from the pid-keyed global side-table
INTERRUPT_SAVED_FPU_STATES (RwLock<BTreeMap<Pid, FpuState>>) into per-PCB
fields fpu: Mutex<FpuState> + fpu_valid: AtomicBool, parallel to the
existing aarch64/riscv64 arch_fpu. save/restore/has/clear_fpu_state now
resolve the PCB via PROCESS_TABLE.find_by_pid instead of the map; the map
and its re-export are deleted. First step of the context-switch rewrite
(docs/superpowers/plans/2026-05-23-ctx-switch-rewrite-implementation-plan.md):
drops one of the two global context maps. Verified: minimal repro boots
zero TRAP (FPU correct across switches).
…h rewrite phase 2)

Introduce the standard ret-based kernel context switch (cpu_switch: push
callee-saved + return addr, swap rsp, pop, ret) and build_initial_switch_frame
that seeds a fresh kernel stack with a fake switch frame. Add pcb.kernel_rsp to
hold a parked task's switch rsp. None of this is routed yet; it is exercised
only by a feature-gated (nonos-cpuswitch-selftest) kernel<->kernel round-trip
self-test run at INIT.

This is the inert groundwork for the phase-4 cutover that replaces the
setjmp/longjmp + INTERRUPT_SAVED_CONTEXTS mechanism.

Verified: target build clean with and without the feature; with the feature the
virtio-rng repro boots and prints "[CPUSWITCH] selftest PASS" with zero faults;
without it the new code is dead.
…switch rewrite phase 3)

Add the two cpu_switch resume targets (first_entry_trampoline,
resume_user_trampoline) that drive the existing first-entry / preempt-resume
tails, and seed pcb.kernel_rsp with a fake switch frame pointing at them:
first-entry in setup_initial_user_pcb_x86_64, preempt-resume in try_resume.
The old dispatch path still drives every resume; kernel_rsp is populated in
parallel and is not yet consumed.

Deviation from the plan: the preempt-case frame is built on the resume side
(try_resume), not in the timer ISR. Writing a switch frame at kstack_top-56
during the timer trampoline would clobber the in-flight interrupt frame on the
same stack; the resume side runs while the target is parked and its kernel
stack top is idle, so it is the safe choke point. restore_user_context_iretq
pushes its iretq tuple on the dispatcher stack via rdi, so the seeded frame
never collides.

Frame population is always-on (phase 4 consumes it); only the [CPUSWITCH]
trace is behind nonos-cpuswitch-selftest.

Verified: target build clean with and without the feature; with the feature the
virtio-rng repro prints "first-entry kernel_rsp set" for every spawned task and
"preempt kernel_rsp set" on every resume, zero faults, and the boot is unchanged
(same proof_io starvation loop the phase-4 cutover fixes).
…witch rewrite phase 4a)

Cut the cooperative scheduler over to the ret-based cpu_switch. yield and
preempt no longer setjmp via Context::save_to + park in INTERRUPT_SAVED_CONTEXTS;
they call switch_to_process, which now returns when the task is scheduled again.
Resume is a single unified path (dispatch.rs): prepare_resume installs the next
task's TSS.RSP0/CR3/state/FPU/user-rsp on the outgoing (global) kernel stack,
then cpu_switch swaps stacks. A never-run task lands on its first_entry_
trampoline frame; an already-run task resumes exactly where it parked inside its
own preempt/yield call, and the iretq/SYSRET frame still on its kernel stack
carries it back to userspace. resume_user_trampoline is dropped: a preempted
task needs no trampoline in this model.

Deleted the old per-mode arch paths (first_entry/resume/kernel_thread) folded
into resume_env + the trampoline; the setjmp/longjmp machinery (Context::save_to/
restore, CONTEXT_JUST_RESTORED, INTERRUPT_SAVED_CONTEXTS) stays for now, used
only by signal delivery + suspend/resume, and is removed in 4b.

build_initial_switch_frame now lands the trampoline at rsp = 8 (mod 16), the
SysV state right after a call, so the target's SSE spills stay 16-aligned. The
prior frame left rsp 16-aligned, which #GP'd the first switch into a never-run
task (movaps on a misaligned spill) once real code ran on it.

prepare_resume tolerates kernel_stack_top == 0 (skips TSS.RSP0) so the boot/init
task, which runs on the boot stack, can be parked and resumed.

Verified: target build clean with and without nonos-cpuswitch-selftest; the
virtio-rng repro boots zero-TRAP for the full 130 s window, the voluntary yield
now resumes (bidirectional init<->capsule switching), and init completes
yield_after_spawns and proceeds to launch_final_payload (forward progress that
was impossible while the yield never returned).
…x-switch rewrite phase 4b)

The restored-flag bounce guard (CONTEXT_JUST_RESTORED + set_restored_flag/
was_just_restored/clear_restored_flag) existed only to stop the old setjmp/
longjmp yield+preempt from double-saving when a restored task immediately took
a timer interrupt. Phase 4a deleted those callers, so the flag has no readers.

Drop the static, the three flag fns, and Context::restore's now-pointless
set_restored_flag() call. Context::save_to/save and Context::restore stay:
signal delivery (syscall_return, signal/delivery/install) and suspend/resume
(suspend.rs) still legitimately use the Context type + INTERRUPT_SAVED_CONTEXTS,
which are no longer scheduler state and are left intact.

Verified: target build clean; virtio-rng repro boots zero-TRAP for 125 s,
behavior identical to 4a (dead-code removal only).
Capsule INTx MkIrqBind always failed with GsiNotFound: the broker's IO-APIC
backend (arch::x86_64::interrupt::ioapic) was never initialized, so its IOAPICS
registry was empty and program_route_external's locate() found no chip. The
boot path only ran the legacy sys::apic::ioapic programmer, which drives kernel
IRQs but does not populate the broker registry.

Wire nonos_ioapic::init() into sys::apic::init() with the MADT IOAPIC/ISO
descriptors (falling back to the 0xFEC00000 default the legacy path uses when
the MADT IOAPIC table parses empty, as it does under this OVMF). Fix the
broker's ioapic map_mmio: it referenced an undefined __nonos_alloc_mmio_va
(dead since the subsystem was never called) and, once live, a raw-physical
0xFEC00000 access faulted because the identity map is torn down by capsule-spawn
time. Resolve the register window through the persistent directmap
(phys_to_virt) instead, matching how the kernel reaches physical memory
post-handoff.

With this the gpu capsule's IRQ binds: zero bind/route/IOAPIC faults across the
boot, and it now advances past bind into device init. (A separate downstream
virtio-gpu "device timeout"/"claim failed" remains; not an IRQ issue.)

A proper UC MMIO mapping for the APIC region (vs the WB directmap, fine under
QEMU) is the broader APIC-MMIO-addressing cleanup tracked with the LAPIC #PF.
The virtio-gpu driver mapped the wrong BAR (VGA framebuffer, BAR0) because it
guessed registers via "first MMIO BAR" and keyed modern/legacy on the device id
alone. On a modern virtio device the register structures live in whatever BAR
the vendor caps name (BAR2 @ 0x1000/0x2000/0x3000 for QEMU virtio-vga), so every
bring-up read/wrote garbage and the device never initialized (timeout / bogus
queue size).

Capsules cannot read PCI config space, so the kernel now parses the virtio
vendor caps (cfg_type common/notify/device/isr) into a VirtioPciCfg
(get_virtio_info, mirroring the MSI-X parser), stores it on PciDevice, and
publishes the BAR+offsets through DeviceRecord (wire size 176 -> 200; libc
mirror + size asserts updated; the other driver capsules' empty_record gain the
zeroed fields). The gpu driver maps the common-cfg BAR at its cap offset and
bases its modern registers there, with notify at notify_off - common_off.

With this the virtio-gpu fully initializes under a modern device (no
disable-modern): IRQ binds, control queue round-trips, and get_display_info /
create_resource_2d / attach_backing / set_scanout all succeed. (Surface
registration is the next blocker: the surface registry translates the capsule
DMA VA through the kernel page table instead of the capsule's — separate bug.)

Requires booting the GPU without disable-modern=on so the modern caps exist.
…table

do_register walked the kernel's PAGING_MANAGER (translate_address) to resolve
the surface descriptor's base_va to physical frames, but base_va is a capsule
user VA. The kernel is upper-half with PML4[0] cleared, so the kernel table has
no capsule user mappings and every page resolved to None -> EFAULT, rejecting
the surface. Add usercopy::user_page_phys, which walks the active (capsule)
table the same way usercopy reads user buffers, and use it per page.

Surface registration still requires the capsule to hold GraphicsSurfaceCreate;
the virtio-gpu driver capsule does not yet (its signed manifest must grant it),
so this fix is not yet exercised end-to-end — but it removes a wrong-address-
space bug any surface producer would hit.
Set the virtio-gpu capsule's required caps to 0x1FB118 (adds GraphicsSurface
Create|Map) so it may register/share its primary scanout surface, and advance
the nonos-data trust-keystore pointer to the re-signed scratch chain
(915a3cf). With this the lean desktop boots without disable-modern and the
compositor presents a live wallpaper through the virtio-gpu framebuffer.
disable-modern=on hides the modern virtio PCI capabilities the kernel
parses to locate the gpu register BARs. Without them the gpu driver
cannot claim or DMA-map and the compositor falls back to GOP. The
hand-rolled bring-up command already omitted the flag; align the run
target with it so make nonos-mk-run-* exercises the working path.
allocate_frame scatters single-frame allocations across the whole
bitmap at a randomized index. By the time the desktop profile spawns
the gpu, that pseudo-random placement leaves no multi-MB contiguous
free run, so alloc_contiguous for the primary surface (768 frames /
3 MiB) returns NoMemory and the gpu cannot map its framebuffer.

Carve a top reserve (contig_split) that the randomized single-frame
path never touches, so first-fit find_contiguous_free always has an
unfragmented window for framebuffer-sized DMA grants.
run() returned run_gop_once() before ever attempting the virtio path,
so the compositor always drew into the GOP framebuffer even when the
gpu surface was available. Once the gpu owns the scanout the GOP
framebuffer is no longer presented, so this left the screen blank.

Try run_virtio_once() first (the existing retry loop waits for the
gpu to come up) and fall back to GOP only when virtio never appears,
matching the "fallback" the marker already advertises.
attach_surface mapped the shared surface pages READ|WRITE without USER,
so the CPL=3 compositor took a U/S protection fault the instant it
touched its attached framebuffer (read of a present supervisor page).
Add PagePermissions::USER so the receiver capsule can read and write
the surface it attached, matching every other user-page mapping.
The .superpowers/ tree holds local brainstorm/session scratch state,
not source. Untrack it and add it to .gitignore so it stays local.
Copilot AI review requested due to automatic review settings May 24, 2026 12:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds multiple debug/dev hardening capabilities across the kernel and userland, expands the device-broker ABI to surface modern virtio PCI capability-derived register locations, and adjusts the QEMU run target to include a GPU by default—together aimed at improving bring-up reliability and debugging for the desktop/graphics stack.

Changes:

  • Introduces new debug/dev feature flags (heap corruption quarantine/logging, cpu_switch selftest, kernel-stack writer trap) and a “lean desktop” boot mode.
  • Extends DeviceRecord ABI and PCI probing to expose virtio modern register window metadata; updates virtio-gpu capsule discovery/MMIO setup to consume it.
  • Improves framebuffer/graphics present paths and QEMU run configuration (GPU enabled by default).

Reviewed changes

Copilot reviewed 128 out of 154 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
userland/libc/src/broker/types.rs Extends broker ABI DeviceRecord with virtio modern register metadata and updates size assert.
userland/compositor/src/setup/prime.rs Adds GOP fallback compositor mode using display dimensions + mmap-backed buffer.
userland/compositor/src/frame_pacer/tick.rs Presents via nonos_surface_present_full when using GOP fallback context.
userland/capsule_net_sockets/src/server/handlers/setsockopt.rs Refactors early returns to explicit respond(...); return;.
userland/capsule_net_sockets/src/server/handlers/getsockopt.rs Refactors early returns and match block termination.
userland/capsule_net_nym/src/server/handlers/surb.rs Refactors error handling to explicit respond(...); return; and expands credential error mapping.
userland/capsule_net_nym/src/server/handlers/set_topology.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/set_timing.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/set_authority.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/send.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/send_reply.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/recv.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/open.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/gateway.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/cover.rs Refactors error handling to explicit respond + return.
userland/capsule_net_nym/src/server/handlers/close.rs Refactors error handling to explicit respond + return.
userland/capsule_net_dns/src/server/handlers/resolve_common.rs Wraps mk_yield() in a block for consistency.
userland/capsule_driver_xhci/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_virtio_rng/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_virtio_net/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_virtio_gpu/src/setup/sequence.rs Adjusts register accessor call to use Found (modern virtio support).
userland/capsule_driver_virtio_gpu/src/setup/mmio.rs Changes regs setup to use virtio cap-derived common/notify offsets.
userland/capsule_driver_virtio_gpu/src/discover.rs Adds virtio-cap-aware discovery path for modern virtio register window.
userland/capsule_driver_virtio_gpu/Capsule.mk Updates required capability mask/comment for virtio-gpu capsule.
userland/capsule_driver_virtio_blk/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_rtl8169/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_rtl8139/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_ps2_input/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_nvme/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_iwlwifi/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_i2c_pci/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_hda/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_e1000/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_driver_ahci/src/discover.rs Updates empty_record() for expanded DeviceRecord.
userland/capsule_crypto/src/server/handlers/hkdf_sha256.rs Fixes hmac_sha256 call to avoid taking &prk of an already-referenced array.
userland/capsule_crypto/Cargo.lock Adds x25519-dalek (+ deps) to lockfile.
src/userspace/init/entry.rs Adds cpu_switch selftest hook + lean desktop spawn gating.
src/usercopy/mod.rs Adds helper to translate user VA to phys via capsule page tables.
src/syscall/dispatch/router/surface_handlers.rs Uses capsule-address-space translation for surface registration frames.
src/syscall/dispatch/router/graphics_present.rs Adds cache flush after framebuffer blit (intended for directmap fallback).
src/sys/apic/api.rs Adds broker IOAPIC init path based on MADT descriptors.
src/smp/percpu/operations.rs Adds GS-base revalidation, and per-CPU saved user stack helpers.
src/smp/percpu/mod.rs Re-exports new per-CPU helpers.
src/process/userspace/asm.rs Removes verbose debug prints; keeps user-entry proof under feature.
src/process/scheduler/preemption/yield_body.rs Saves per-process user RSP snapshot and updates state transitions.
src/process/scheduler/preemption/switch.rs Saves per-process user RSP snapshot and simplifies resume state handling.
src/process/mod.rs Updates reexports after removing global saved FPU map.
src/process/core/table/create.rs Adds PCB fields for saved user stack, kernel_rsp, and per-PCB FPU storage.
src/process/core/suspend.rs Moves x86_64 FPU save/restore from global map into PCB.
src/process/core/pcb.rs Extends PCB with saved user stack, kernel_rsp, and x86_64 FPU slot.
src/process/context/full/save.rs Removes per-CPU “just restored” bookkeeping from Context save path.
src/process/context/full/restore.rs Removes restored-flag set in Context restore path.
src/memory/phys/types/allocator_state.rs Adds contig_split() to reserve frames for contiguous allocations.
src/memory/phys/allocator/alloc.rs Uses contig_split() to limit regular frame allocation range.
src/memory/paging/manager/faults/handler.rs Rejects user-mode faults on kernel-half addresses early.
src/memory/heap/types/quarantine.rs Adds debug-only free quarantine ring + poison checking.
src/memory/heap/types/mod.rs Wires quarantine module behind nonos-heap-debug.
src/memory/heap/types/dealloc_impl.rs Adds debug-only corruption logging and quarantine path for frees.
src/memory/heap/manager/init.rs Prevents re-init based on bootstrap usage flag.
src/kernel_core/surface_registry/share.rs Maps attached surfaces with USER permission.
src/kernel_core/process_spawn/user_stack.rs Zeroes user stack frames and adds debug watch plumbing behind feature.
src/kernel_core/process_spawn/pending_stack_free.rs Prevents freeing the currently-in-use kernel stack in deferred drain.
src/kernel_core/init/framebuffer.rs Adds directmap fallback for framebuffer mapping + draws a boot desktop.
src/kernel_core/init/entry.rs Calls draw_desktop() during arch framebuffer init.
src/ipc/nonos_inbox/registry.rs Adds interrupt disable guard around inbox registry mutations.
src/interrupts/safety/context.rs Makes interrupt-context cpu_id GS-independent via crate::smp::cpu_id().
src/interrupts/isr/timer_trampoline.rs Ensures GS base is valid on timer trap entry.
src/interrupts/handlers/exceptions/page_fault.rs Adds debug-only user RSP vicinity dump for a specific investigation.
src/hardware/virtio_gpu_capsule/spawn.rs Adds Debug capability for virtio-gpu capsule spawn.
src/hardware/broker/table.rs Populates virtio cap-derived fields in broker DeviceRecord.
src/hardware/broker/platform.rs Uses struct update syntax to fill new DeviceRecord fields.
src/hardware/broker/device.rs Extends broker DeviceRecord with virtio modern register metadata and size assert.
src/drivers/pci/types/virtio.rs Introduces VirtioPciCfg type for parsed modern virtio PCI caps.
src/drivers/pci/types/mod.rs Exposes new virtio PCI cfg type.
src/drivers/pci/types/device.rs Adds optional virtio cap info to PciDevice.
src/drivers/pci/manager/probe.rs Collects virtio vendor capability info during PCI probe.
src/drivers/pci/capabilities/mod.rs Re-exports virtio cap helper.
src/drivers/pci/capabilities/helpers.rs Parses virtio vendor capabilities into VirtioPciCfg.
src/crypto/hash/sha512/hasher.rs Removes debug serial prints from Sha512 constructor.
src/boot/handoff/types/tests.rs Adds golden offset/size ABI pin tests for BootHandoffV1.
src/boot/handoff/types/handoff.rs Adds const-eval ABI pin asserts for BootHandoffV1.
src/arch/x86_64/interrupt/ioapic/mmio.rs Switches IOAPIC MMIO mapping to directmap translation with bounds checking.
src/arch/x86_64/diag/mod.rs Exposes user-stack dump helper behind debug feature.
src/arch/x86_64/diag/dump_trap.rs Adds debug-only dump of user memory around RSP.
src/arch/x86_64/context/switch/trampolines.rs Adds first-entry trampoline for cpu_switch-based scheduling.
src/arch/x86_64/context/switch/resume_env.rs Refactors resume environment staging (TSS/CR3/FPU/user RSP restore).
src/arch/x86_64/context/switch/mod.rs Replaces old switch modules with cpu_switch/resume_env/trampolines.
src/arch/x86_64/context/switch/kernel_thread.rs Removes old kernel-thread resume path.
src/arch/x86_64/context/switch/first_entry.rs Removes old first-entry path.
src/arch/x86_64/context/switch/dispatch.rs Switches scheduler dispatch to cpu_switch-based kernel stack swap.
src/arch/x86_64/context/switch/cpu_switch.rs Adds ret-based cpu_switch + initial switch-frame builder.
src/arch/x86_64/context/switch/cpu_switch_selftest.rs Adds boot-time cpu_switch selftest behind feature.
src/arch/x86_64/context/setup.rs Seeds initial kernel_rsp switch frame for first-entry trampoline.
src/arch/x86_64/context/mod.rs Re-exports switch helpers (and selftest) at arch context layer.
rustc-ice-2026-05-15T10_55_04-43970.txt Adds recorded rustc ICE log artifact.
nonos-bootloader/src/handoff/types/handoff.rs Adds const-eval ABI pin asserts for bootloader BootHandoffV1.
Makefile Enables QEMU GPU by default for serial run; removes disable-modern=on.
eK_notes/graphics_audit_prompt.md Adds a graphics capsule maturity audit prompt doc.
docs/superpowers/specs/2026-05-22-kstack-writer-trap-design.md Adds design spec for kernel-side watchpoint trap.
docs/superpowers/specs/2026-05-20-trust-verifier-nondeterminism-design.md Adds design spec for diagnosing trust verifier nondeterminism.
docs/superpowers/plans/wp-phys-compare.py Adds LLDB/QEMU monitor helper script for VA→PA comparisons.
docs/superpowers/plans/wp-directmap-catch.py Adds LLDB/QEMU monitor helper script to arm directmap watchpoints.
docs/superpowers/plans/NOTE-FOR-EK-gui-blocker.md Adds note summarizing GUI blocker status and plan.
docs/superpowers/plans/2026-05-24-virtio-pci-cap-discovery.md Adds implementation plan for virtio PCI cap discovery.
docs/superpowers/plans/2026-05-23-ROOT-CAUSE-pcpu-user-stack-clobber.md Adds root-cause writeup for per-CPU user stack clobber across preemption.
docs/superpowers/plans/2026-05-23-ctx-switch-rewrite-implementation-plan.md Adds detailed implementation plan for context switch rewrite.
docs/superpowers/plans/2026-05-22-ROOT-CAUSE-frame-collision.md Adds (superseded) root-cause note on frame collision theory.
docs/superpowers/plans/2026-05-22-ctx-switch-rewrite-PROMPT.md Adds investigation prompt for context-switch rewrite.
docs/superpowers/plans/2026-05-22-CONTEXT-gui-blocker.md Adds comprehensive context doc for GUI blocker investigation.
docs/superpowers/plans/2026-05-21-userland-crash-blocker.md Adds crash blocker tracking doc for userland.
docs/superpowers/plans/2026-05-21-gui-rca-progress.md Adds GUI bring-up RCA progress doc.
docs/plans/user_surface_pan(rusty).md Adds Plan A user-surface roadmap doc.
docs/bootloader-investigation-prompt.md Adds bootloader hardening investigation prompt doc.
docs/audits/bootloader-hardening/04-boot-ui-direction.md Adds boot UI direction document for hardening audit.
Cargo.toml Adds new debug/dev feature flags and “lean desktop” feature.
.gitignore Ignores .superpowers/ scratch artifacts.

Comment on lines 105 to 107
let mut reg = REGISTRY.write();
let _irq = crate::interrupts::disable_interrupts_guard();
if reg.map.contains_key(module) {
Comment on lines +99 to 102
// The GOP framebuffer is reached through the write-back directmap when
// map_framebuffer is unavailable; flush so the stores hit the scanout.
unsafe { core::arch::asm!("wbinvd", options(nostack, preserves_flags)) };
SyscallResult::success_audited(0)
Comment on lines 123 to 128
ArchSpecificHandoff::X86_64 { v1 } => {
#[cfg(target_arch = "x86_64")]
init_memory(v1);
init_framebuffer(v1);
super::framebuffer::draw_desktop();
}
Comment on lines +94 to +99
let base_va = match crate::memory::mmio::map_framebuffer(PhysAddr::new(base), map_len) {
Ok(v) => v,
Err(_) => {
crate::sys::serial::println(b"[FBINIT] map_framebuffer failed; using directmap");
VirtAddr::new(crate::memory::layout::DIRECTMAP_BASE + base)
}
Comment on lines +62 to +69
fill_rect(fb, 0, 0, fb.width, fb.height, 0xFF1A2738);
fill_rect(fb, 0, 0, fb.width, 28, 0xFF0C141E);
fill_rect(fb, 0, fb.height.saturating_sub(56), fb.width, 56, 0xFF0C141E);
let dock_x = fb.width / 2;
fill_rect(fb, dock_x.saturating_sub(120), fb.height.saturating_sub(48), 240, 40, 0xFF1E66A8);
// Push write-back directmap stores out to the scanout device.
unsafe { core::arch::asm!("wbinvd", options(nostack, preserves_flags)) };
crate::sys::serial::println(b"[DESKTOP] drawn");
Comment on lines +14 to +15
# IPC|Memory|Debug|Driver|DeviceEnum|Mmio|Irq|Dma|Pio = 0x1F8118
CAPSULE_REQUIRED_CAPS := 0x1FB118
Comment on lines +17 to +21
//! Standard `ret`-based kernel context switch. Saves callee-saved regs + the
//! return address on the outgoing kernel stack, stores rsp in `*prev_rsp_slot`,
//! loads `next_rsp`, pops, and `ret`s into the next task's resume point. This
//! replaces the setjmp/longjmp + `INTERRUPT_SAVED_CONTEXTS` mechanism. Not yet
//! routed (phase 2): exercised only by the self-test until the phase-4 cutover.
Comment on lines +49 to +54
match prev {
Some(p) => unsafe { cpu_switch(p.kernel_rsp.as_ptr(), next_rsp) },
None => {
let mut discard = 0u64;
unsafe { cpu_switch(&mut discard as *mut u64, next_rsp) }
}
Comment on lines +49 to +62
if r.virtio_present != 0 {
let cb = r.virtio_common_bar as usize;
let size = if cb < r.bars.len() { r.bars[cb].size } else { 0 };
return Some(Found {
device_id: r.device_id,
irq_line: r.irq_line,
register_bar: r.virtio_common_bar,
register_kind: BAR_KIND_MMIO,
register_size: size,
pci_device: r.device,
has_virtio: true,
common_off: r.virtio_common_off,
notify_rel: r.virtio_notify_off.saturating_sub(r.virtio_common_off),
});
Comment on lines +35 to 41
pub fn regs(self, dev: Found) -> Regs {
match self {
Self::Mmio(g) if pci_device == VIRTIO_GPU_MODERN => {
Regs::mmio_with_notify(g.user_va, MOD_NOTIFY_BASE)
}
Self::Mmio(g) if dev.has_virtio => Regs::mmio_with_notify(
g.user_va + dev.common_off as u64,
dev.notify_rel as usize,
),
Self::Mmio(g) => Regs::mmio(g.user_va),
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants