Stage 3 follow-on: fix stack-ownership corruption + DoE switch columns (FABRIC-3.md §XXVIII.1)
DoE CSV gained 6 switch-signal columns (switch_count_cumulative, switch_current_slot, switch_*_readiness, switch_ticks_since), and verifying them with a boot-time HB-ON probe surfaced a real livelock: the preemption checkpoint could fire inside a VM-EXEC-nested execute_colon_word() call and switch away from a stack it didn't own, parking a borrowed region of the caller's stack under the wrong VM's saved-context pointer. The trampoline bounce was the visible (safe) half of this; the corruption was the quiet half, live in every prior "clean" Stage 3 boot without ever showing up in the log. Fixed by gating the checkpoint on being at the outermost vm_interpret() call (g_vm_interpret_depth / sk_vm_at_outermost_interpret(), vm_core.c), per Bob's decision. Also fixed two related bugs found in the same pass: g_switch_back_to was a single global stale after first entry, now per-VM state (native_switch_back_to); note_switch_performed() fired on resume instead of switch-out, now called before the switch. Verified on all 3 architectures: steady log growth (no freeze), zero leaked QEMU processes, DoE columns internally consistent, Hermes/Artemis confirmed genuinely executing (not just trampoline-bouncing). Temporary HB-ON boot probe reverted after capture. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UNhH1mhi52i6Qihh7ZV5S
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
986d042aa7
commit
862d7d9c48
@@ -56,6 +56,11 @@ static int g_slot_count;
|
||||
static int g_pending;
|
||||
static VMUuid g_pending_target;
|
||||
|
||||
/* DoE CSV exposure (FABRIC-3.md §XXVIII Stage 3 follow-on, 2026-09-13). */
|
||||
static int g_current_slot_cached = -1;
|
||||
static uint64_t g_switch_count;
|
||||
static uint32_t g_ticks_since_switch;
|
||||
|
||||
static int slot_for_vm_id(VMUuid vm_id) {
|
||||
int i;
|
||||
for (i = 0; i < g_slot_count; i++) {
|
||||
@@ -81,6 +86,9 @@ void sk_vm_switch_signal_tick(void) {
|
||||
current_slot = slot_for_vm_id(current->stadium_vm_id);
|
||||
if (current_slot < 0) return; /* current VM isn't a registered participant */
|
||||
|
||||
g_current_slot_cached = current_slot;
|
||||
g_ticks_since_switch++;
|
||||
|
||||
for (i = 0; i < g_slot_count; i++) {
|
||||
if (i == current_slot) {
|
||||
g_slots[i].readiness = 0;
|
||||
@@ -106,4 +114,36 @@ VMUuid sk_vm_switch_signal_take_pending(void) {
|
||||
return g_pending_target;
|
||||
}
|
||||
|
||||
void sk_vm_switch_signal_note_switch_performed(void) {
|
||||
g_switch_count++;
|
||||
g_ticks_since_switch = 0;
|
||||
}
|
||||
|
||||
uint64_t sk_vm_switch_signal_switch_count(void) {
|
||||
return g_switch_count;
|
||||
}
|
||||
|
||||
uint32_t sk_vm_switch_signal_ticks_since_switch(void) {
|
||||
return g_ticks_since_switch;
|
||||
}
|
||||
|
||||
int sk_vm_switch_signal_current_slot(void) {
|
||||
return g_current_slot_cached;
|
||||
}
|
||||
|
||||
int sk_vm_switch_signal_slot_count(void) {
|
||||
return g_slot_count;
|
||||
}
|
||||
|
||||
uint32_t sk_vm_switch_signal_readiness(int slot) {
|
||||
if (slot < 0 || slot >= g_slot_count) return 0;
|
||||
return g_slots[slot].readiness;
|
||||
}
|
||||
|
||||
uint32_t sk_vm_switch_signal_readiness_of(VMUuid vm_id) {
|
||||
int slot = slot_for_vm_id(vm_id);
|
||||
if (slot < 0) return 0;
|
||||
return g_slots[slot].readiness;
|
||||
}
|
||||
|
||||
#endif /* __STARKERNEL__ */
|
||||
|
||||
Reference in New Issue
Block a user