kernel: Switch to a stack we control for the main task as soon as we leave early boot
All checks were successful
continuous-integration/drone/pr Build is passing

This is probably pointless as the main task only exists up until the point where the Scheduler starts running, but some init code was running into a stack overflow due to the fact that we only had one bootloader-provided page of stack.

This should probably be changed afterwards.
This commit is contained in:
apio 2023-02-18 00:18:42 +01:00
parent 37bbc04719
commit d842443869
Signed by: apio
GPG Key ID: B8A7D06E42258954
3 changed files with 22 additions and 3 deletions

View File

@ -26,5 +26,7 @@ namespace CPU
void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg); void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg);
void print_stack_trace_at(Registers* regs); void print_stack_trace_at(Registers* regs);
[[noreturn]] void bootstrap_switch_stack(u64 stack, void* function);
void pause(); void pause();
} }

View File

@ -295,6 +295,15 @@ namespace CPU
&frame_index); &frame_index);
} }
[[noreturn]] void bootstrap_switch_stack(u64 stack, void* function)
{
asm volatile("mov %0, %%rsp\n"
"jmp *%1"
:
: "r"(stack), "r"(function));
__builtin_unreachable();
}
void pause() void pause()
{ {
asm volatile("pause"); asm volatile("pause");

View File

@ -90,11 +90,19 @@ Result<void> init()
return {}; return {};
} }
extern "C" [[noreturn]] void _start() [[noreturn]] void init_wrapper()
{ {
Init::check_magic();
Init::early_init();
auto rc = init(); auto rc = init();
if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string()); if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string());
CPU::idle_loop(); CPU::idle_loop();
} }
// FIXME: Add a guard page to make sure the stack doesn't end up in random kernel memory. Also reclaim this memory after
// leaving the init task.
extern "C" [[noreturn]] void _start()
{
Init::check_magic();
Init::early_init();
Stack stack { MemoryManager::alloc_for_kernel(8, MMU::ReadWrite | MMU::NoExecute).value(), 8 * ARCH_PAGE_SIZE };
CPU::bootstrap_switch_stack(stack.top(), (void*)init_wrapper);
}