@@ -1191,22 +1191,20 @@ static int semu_run(emu_state_t *emu)
11911191 size_t pfd_count = 0 ;
11921192 int timer_index = -1 ;
11931193
1194- /* Add periodic timer fd (1ms interval for guest timer emulation).
1195- * Only add timer when ALL harts are active (none idle) to allow
1196- * poll() to sleep when any harts are in WFI. When harts are idle,
1197- * timer updates can be deferred until they wake up.
1198- *
1199- * During SMP boot (started_harts < vm->n_hart), always include the
1200- * timer to ensure secondary harts can complete initialization. Only
1201- * apply conditional exclusion after all harts have started.
1202- *
1203- * For single-hart configurations (n_hart == 1), disable
1204- * optimization entirely to avoid boot issues, as the first hart
1205- * starts immediately.
1194+ /* Add periodic timer fd (1ms interval). Excluded when harts are
1195+ * idle to allow poll() sleep, but always included during:
1196+ * 1. Single-hart mode (n_hart == 1)
1197+ * 2. Boot phase (!boot_complete) - prevents deadlock when kernel
1198+ * briefly puts all harts in WFI while waiting for timer IRQ
1199+ * 3. Active execution (idle_harts == 0)
12061200 */
12071201 bool all_harts_started = (started_harts >= vm -> n_hart );
1202+ const uint64_t BOOT_SETTLE_ITERATIONS = 5000 ;
1203+ bool boot_complete =
1204+ all_harts_started &&
1205+ (emu -> peripheral_update_ctr > BOOT_SETTLE_ITERATIONS );
12081206 bool harts_active =
1209- (vm -> n_hart == 1 ) || !all_harts_started || (idle_harts == 0 );
1207+ (vm -> n_hart == 1 ) || !boot_complete || (idle_harts == 0 );
12101208#ifdef __APPLE__
12111209 /* macOS: use kqueue with EVFILT_TIMER */
12121210 if (kq >= 0 && pfd_count < poll_capacity && harts_active ) {
@@ -1227,7 +1225,7 @@ static int semu_run(emu_state_t *emu)
12271225 /* Add UART input fd (stdin for keyboard input).
12281226 * Only add UART when:
12291227 * 1. Single-hart configuration (n_hart == 1), OR
1230- * 2. Not all harts started (!all_harts_started ), OR
1228+ * 2. Boot not complete (!boot_complete ), OR
12311229 * 3. All harts are active (idle_harts == 0), OR
12321230 * 4. A hart is actively waiting for UART input
12331231 *
@@ -1236,7 +1234,7 @@ static int semu_run(emu_state_t *emu)
12361234 * input (Ctrl+A x) may be delayed by up to poll_timeout (10ms)
12371235 * when harts are idle, which is acceptable for an emulator.
12381236 */
1239- bool need_uart = (vm -> n_hart == 1 ) || !all_harts_started ||
1237+ bool need_uart = (vm -> n_hart == 1 ) || !boot_complete ||
12401238 (idle_harts == 0 ) || emu -> uart .has_waiting_hart ;
12411239 if (emu -> uart .in_fd >= 0 && pfd_count < poll_capacity &&
12421240 need_uart ) {
0 commit comments