add smp-retry test for the AP wake retry path

Test hook forces the first wake to fail; the case asserts every core still comes online. Verified it fails when retry is disabled.
This commit is contained in:
Daniel Samson
2026-07-08 13:41:14 +01:00
parent debe815a5c
commit 91f2cfa17b
5 changed files with 46 additions and 0 deletions
+6
View File
@@ -124,6 +124,12 @@ pub fn setSecondaryEntry(entry: *const fn () callconv(.c) noreturn) void {
smp.setSecondaryEntry(entry);
}
/// Test hook: force the next `n` AP wake attempts to fail, so the retry path can be
/// exercised deterministically (see the smp-retry test). No effect when `n` is 0.
pub fn testFailNextWakes(n: u32) void {
smp.testFailNextWakes(n);
}
/// Kernel tick rate: 1000 Hz (1 ms), the scheduler's time quantum.
pub const timer_hz = 1000;
+13
View File
@@ -51,6 +51,14 @@ pub fn setSecondaryEntry(entry: *const fn () callconv(.c) noreturn) void {
secondary_entry = entry;
}
/// Test hook: force the next `n` wake attempts to fail (skipping the actual
/// INIT-SIPI-SIPI), so the retry path can be exercised deterministically. Zero in
/// normal operation — the smp-retry test arms it via `arch.testFailNextWakes`.
var fail_next_wakes: u32 = 0;
pub fn testFailNextWakes(n: u32) void {
fail_next_wakes = n;
}
/// Record the reserved low frame the trampoline uses. Call once at boot. The frame
/// starts inert (identity-mapped RW+NX like all RAM); each wake arms it and disarms
/// it again, so it's only ever executable while a core is climbing.
@@ -101,6 +109,11 @@ pub fn startAp(apic_id: u32, stack_top: usize, percpu: usize, index: usize, cr3:
arm();
defer disarm();
if (fail_next_wakes > 0) { // test hook: simulate a core missing this attempt
fail_next_wakes -= 1;
return false;
}
boot_index = index;
param("ap_tramp_cr3").* = cr3;
param("ap_tramp_stack").* = stack_top;