From 34051167e9426fa995d936fee2bb4e8b46a7c8df Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Thu, 12 Feb 2026 03:23:30 -0300 Subject: [PATCH] fix: allocate dedicated heap kernel stack for PID 0 (idle task) PID 0 previously used the boot stack from assembly (_stack_top), which is not heap-managed. This caused two issues: - TSS esp0 was not updated when switching to PID 0 (kernel_stack was NULL, so the guard in schedule() skipped the update) - If PID 0 were ever reaped or its stack freed, it would corrupt memory since the boot stack is not a kmalloc'd block Now process_init() allocates a 4KB kernel stack via kmalloc and sets TSS esp0 to its top, matching the pattern used by all other processes. --- src/kernel/scheduler.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/kernel/scheduler.c b/src/kernel/scheduler.c index 766c49d..e6cc36e 100644 --- a/src/kernel/scheduler.c +++ b/src/kernel/scheduler.c @@ -632,15 +632,25 @@ void process_init(void) { kernel_proc->tls_base = 0; kernel_proc->clear_child_tid = NULL; + /* Allocate a dedicated kernel stack for PID 0 on the heap. + * This avoids using the boot stack (which is not heap-managed) + * and ensures kfree safety and proper TSS esp0 updates. */ + void* kstack0 = kmalloc(4096); + if (!kstack0) { + spin_unlock_irqrestore(&sched_lock, flags); + uart_print("[SCHED] OOM allocating PID 0 kernel stack.\n"); + for (;;) hal_cpu_idle(); + __builtin_unreachable(); + } + kernel_proc->kernel_stack = (uint32_t*)kstack0; + current_process = kernel_proc; ready_queue_head = kernel_proc; ready_queue_tail = kernel_proc; kernel_proc->next = kernel_proc; kernel_proc->prev = kernel_proc; - // Best effort: set esp0 to current stack until we have a dedicated kernel stack for PID 0 - uintptr_t cur_esp = hal_cpu_get_stack_pointer(); - hal_cpu_set_kernel_stack(cur_esp); + hal_cpu_set_kernel_stack((uintptr_t)kstack0 + 4096); spin_unlock_irqrestore(&sched_lock, flags); } -- 2.43.0