item 4.6: fix Stadium quota-grant ordering; fix aarch64 PSCI SYSTEM_RESET function ID

Artemis's 30-rep surface stress campaign was failing 100% of trials on all
three architectures: stadium_grant_quota() ran after IDENTITY exec in
capsule_birth.c, but Artemis's init.4th auto-runs the stress campaign as
part of that same IDENTITY exec, so every STADIUM-ADMIT call during it hit
a nonexistent quota slot and refused unconditionally. Moved the grant call
before IDENTITY exec. Verified 30/30 reps PASS on amd64, aarch64, and
riscv64 post-fix (was 30/30 FAIL on all three pre-fix).

Also fixed an independent, real bug found during the same acceptance pass:
aarch64's arch_cold_reset() issued PSCI SYSTEM_RESET using the SMC64
calling convention (0xC4000009), which is not a valid PSCI function ID --
SYSTEM_RESET has no SMC64 variant. Corrected to the SMC32 encoding
(0x84000009). This did not resolve the separate aarch64 BYE cold-restart
exception also found in this pass (root cause not yet found, tested and
refuted an interrupt-race hypothesis, documented in FABRIC-2.md Section I
for follow-up) but is a genuine spec fix worth keeping regardless.

Full writeup, evidence, and the still-open aarch64 crash investigation in
FABRIC-2.md Sections H and I.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-18 14:53:18 -04:00
co-authored by Claude Sonnet 5
parent 48ab9945de
commit 8d90538801
29 changed files with 1507970 additions and 164 deletions
+6 -2
View File
@@ -125,9 +125,13 @@ void arch_halt(void)
void arch_cold_reset(void)
{
arch_disable_interrupts();
/* PSCI SYSTEM_RESET (SMC64 function 0xC4000009) */
/* PSCI SYSTEM_RESET (function 0x84000009). SYSTEM_RESET takes no
* arguments and has no SMC64 variant defined by the PSCI spec -- only
* the SMC32 encoding is valid. The prior 0xC4000009 (SMC64 convention)
* was not a real PSCI function ID, causing an unhandled exception
* (EC=0, "Unknown reason") on the SMC call instead of a reset. */
__asm__ volatile (
"mov x0, #0xC4000000\n"
"mov x0, #0x84000000\n"
"movk x0, #0x0009\n"
"smc #0\n"
::: "x0", "memory"
+14 -9
View File
@@ -479,6 +479,20 @@ CapsuleRunResult capsule_birth_baby(
* own reservoir, not vm_uuid_hera()'s (item 4.1's hardcoded default). */
((VM *)new_vm)->stadium_vm_id = vm_id;
/* item 4.6 fix (FABRIC-2.md, 2026-08-18): granted here, before IDENTITY
* exec, not after a confirmed live birth as item 4.1a originally placed
* it. item 4.1a's placement assumed no VM's own IDENTITY code would ever
* need a Stadium quota before birth completes -- true until item 4.6's
* Artemis capsule started auto-running a block-admission stress campaign
* as part of her own init.4th load. Without a quota yet, every
* STADIUM-ADMIT during that campaign refused unconditionally (quota
* slot < 0), 100% of trials, on all three architectures. Trade-off this
* introduces: a VM that dies stillborn below (IDENTITY exec fails) has
* still consumed half of Hera's free list, with no rollback -- accepted
* because stadium_grant_quota() failure was already non-fatal and a
* stillbirth here is the rare case, not the common one. */
(void)stadium_grant_quota(vm_id, vm_uuid_hera());
const uint8_t *payload = capsule_get_payload(cap, arena);
if (!payload) {
entry->state = VM_STATE_STILLBORN;
@@ -507,15 +521,6 @@ CapsuleRunResult capsule_birth_baby(
capsule_parity_log_birth(vm_id, cap->capsule_id, cap->content_hash, dict_hash);
/* item 4.1a: one-time initial quota grant, from Hera's free list. Placed
* after a live birth is confirmed (not gating IDENTITY exec above) --
* this baby can hold no Stadium resident until item 4.2's own work gives
* her a reason to. Failure is not fatal: a VM with no quota today is the
* status quo every VM had before this item existed, so she is simply
* born without one and every stadium_word_dispatch() for her stays a
* harmless refusal, same as any VM without a quota. */
(void)stadium_grant_quota(vm_id, vm_uuid_hera());
if (out_vm_id) *out_vm_id = vm_id;
if (out_vm_ctx) *out_vm_ctx = new_vm;
+59
View File
@@ -834,6 +834,65 @@ static void kernel_main_deep(BootInfo *boot_info) {
}
}
/* item 4.6 self-test: a REAL birth (not synthetic), exercising
* capsules/artemis/init.4th's actual migrated block-heat code.
* Artemis's own capsule already runs a full self-test plus a
* 30-rep stress campaign at load (ART-BOOT-ENTRY / block 4170's
* still-enabled ART-STRESS-CAMPAIGN) -- this scaffold only adds
* the conservation-check bracketing item 4.2's Hermes self-test
* used, not a duplicate exercise. Diagnostic only -- production
* boot still never auto-births Artemis (init.4th's BIRTH stays
* commented out). */
console_println("Artemis 4.6 migration self-test: birthing...");
vm_interpret(mama, "S\" Artemis\" BIRTH");
{
VMRegistryEntry entry;
if (capsule_vm_find_by_name_nocase("Artemis", &entry) == 0 &&
entry.state == VM_STATE_LIVE) {
VM *artemis_vm = (VM *)entry.vm_ptr;
console_println("Artemis 4.6 self-test: ARTEMIS-K after boot-time load:");
artemis_vm->error = 0;
vm_interpret(artemis_vm, "ARTEMIS-K .");
console_println("");
print_uint(" DBG err after ARTEMIS-K=", (uint64_t)artemis_vm->error);
print_uint(" DBG stadium_resident_sum(Artemis)=", stadium_resident_sum(entry.vm_id));
print_uint(" DBG stadium_reservoir_peek(Artemis)=", stadium_reservoir_peek(entry.vm_id));
/* item 4.6 Done-when: "a resident cell's evict-credit landing
* in the correct VM's reservoir", same check 4.2 made for
* Hermes. Allocate one fresh block explicitly, confirm the
* reservoir/resident split, free it, confirm both settle
* back the same way. */
console_println("Artemis 4.6 self-test: explicit alloc/free round-trip...");
artemis_vm->error = 0;
vm_interpret(artemis_vm, "BLK-ALLOC DUP . CR");
print_uint(" DBG err after BLK-ALLOC=", (uint64_t)artemis_vm->error);
print_uint(" Artemis resident_sum (post-alloc)=", stadium_resident_sum(entry.vm_id));
print_uint(" Artemis reservoir (post-alloc)=", stadium_reservoir_peek(entry.vm_id));
artemis_vm->error = 0;
vm_interpret(artemis_vm, "BLK-FREE");
print_uint(" DBG err after BLK-FREE=", (uint64_t)artemis_vm->error);
print_uint(" Artemis resident_sum (post-free)=", stadium_resident_sum(entry.vm_id));
print_uint(" Artemis reservoir (post-free)=", stadium_reservoir_peek(entry.vm_id));
console_println("Artemis 4.6 self-test: ARTEMIS-K after round-trip:");
artemis_vm->error = 0;
vm_interpret(artemis_vm, "ARTEMIS-K .");
console_println("");
/* item 4.6 Done-when: both VMs' conservation checks close
* independently -- Artemis's own resident+reservoir sum
* first, then Hera's again (unaffected by Artemis's
* activity above). */
stadium_words_print_boot_diagnostics(entry.vm_id);
vm_interpret(mama, "S\" Artemis\" KILL");
console_println("Artemis 4.6 self-test: killed, resting state restored");
stadium_words_print_boot_diagnostics(vm_uuid_hera());
} else {
console_println("Artemis 4.6 self-test: birth registry lookup FAILED");
}
}
/*
* Runtime --doe flag: inject "EXEC-DOE BYE" if requested via boot args.
* Checked before SK_STARTUP_FORTH so a runtime --doe takes precedence.