Stage 1: per-VM native stacks, allocated but not yet executed on (FABRIC-3.md §XXVIII)
Build / build-amd64-iso (push) Canceled after 0s
Build / build-aarch64-iso (push) Canceled after 0s
Build / build-riscv64-img (push) Canceled after 0s

Second stage of the preemptive context-switching plan. Every VM (Hera,
every capsule_birth_baby()-born VM including WIREBIND identities) now
gets its own dedicated 2 MiB native C stack at birth -- but nothing runs
on it yet, that's Stage 2. Pure allocation-machinery proof.

Design correction made before writing code: the plan called for cloning
sk_vm_arena_alloc()'s guard-page pattern, but that pattern turns out to
be Mama-only -- host_services.c's kernel_alloc() gives every baby VM a
plain kmalloc() block for its dictionary arena, not a real guarded PMM
allocation. Stacks get the real treatment instead (new
sk_vm_native_stack_alloc()/_free() in arena.c): independent
pmm_alloc_contiguous() + guard pages for every VM without exception, no
singleton, no kmalloc fallback -- a stack overflow is exactly the
failure mode guard pages exist for, and a corrupted stack could corrupt
whatever saved context Stage 2 trusts.

2 MiB size matches this project's own established kernel-stack
convention (g_kernel_stack/g_rpi5_native_stack), not a guess -- that one
shared 2 MiB stack today already carries all VMs' combined nested
VM-EXEC recursion.

Three new VM struct fields, freed in vm_cleanup() alongside the existing
call_stack free. Allocation failure is non-fatal to birth.

All 3 architectures re-verified clean boot to ok>, no native-stack
allocation failures for any Tripod-fleet VM.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016UNhH1mhi52i6Qihh7ZV5S
This commit is contained in:
Robert Allan James
2026-09-13 14:30:46 -04:00
co-authored by Claude Sonnet 5
parent 15672ce17c
commit 57ac3fc304
15 changed files with 27337 additions and 1 deletions
@@ -59,6 +59,7 @@
#include "starkernel/capsule_birth.h"
#include "starkernel/capsule_run.h"
#include "starkernel/capsule_vm_physics.h"
#include "starkernel/vm/arena.h" /* FABRIC-3.md §XXVIII Stage 1 -- sk_vm_native_stack_alloc() */
#include "vm_internal.h"
#include "platform_time.h"
#include "test_runner/include/test_runner.h"
@@ -266,6 +267,21 @@ int sk_vm_bootstrap_parity(ParityPacket *out) {
return -1;
}
/* FABRIC-3.md §XXVIII, Stage 1 (2026-09-13): Hera gets her own native
* stack too, same as every baby/WIREBIND VM (capsule_birth_baby()).
* Not fatal on failure, same reasoning as there -- nothing executes on
* this yet (Stage 2). */
{
sk_vm_native_stack_t ns;
if (sk_vm_native_stack_alloc(&ns) == 0) {
vm->native_stack_paddr = ns.paddr;
vm->native_stack_guard_vaddr = ns.guard_vaddr;
vm->native_stack_top = ns.stack_top;
} else {
console_println("VM: Hera native stack allocation failed");
}
}
/* Capsule subsystem: hooks, registry (Hera), run log.
* Called exactly once here for Mama — child VMs go through
* capsule_birth_baby() which never calls vm_init_with_host(). */