fix: kernel concurrency, interrupt context, and user VA safety

This commit is contained in:
2026-08-01 15:43:38 +02:00
parent f222bf1f04
commit b1c55073c7
71 changed files with 2654 additions and 1092 deletions
+12 -1
View File
@@ -13,6 +13,7 @@
#include <Memory/PageFrameAllocator.hpp>
#include <Sched/Scheduler.hpp>
#include <Sched/CrashReport.hpp>
#include <Hal/SmpBoot.hpp>
#include <Timekeeping/ApicTimer.hpp>
namespace Hal {
@@ -93,6 +94,14 @@ namespace Hal {
// If the fault originated in user-mode (ring 3), kill the process
// instead of panicking the entire system.
if (fromUser && Sched::GetCurrentPid() >= 0) {
// Interrupt gates arrive with IF clear. Full process teardown can
// wait on device completions, sibling CPUs, and wall-clock-bounded
// recovery paths, so leaving IF clear here can stop the BSP clock
// and its local device IRQs indefinitely. GS is already the kernel
// per-CPU base, and timer/IPI scheduling refuses to switch away
// from a ring-0 frame, so nested hardware IRQs are safe now.
asm volatile("sti" ::: "memory");
auto* proc = Sched::GetCurrentProcessPtr();
auto* regs = GetExceptionRegs(i, frame);
Kt::KernelLogStream(Kt::ERROR, "Exception")
@@ -183,6 +192,7 @@ namespace Hal {
{
bool fromUser = (frame->CS & 3) == 3;
if (fromUser) asm volatile("swapgs");
auto* cpu = Smp::TryGetCurrentCpuData();
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));
@@ -190,7 +200,8 @@ namespace Hal {
// Bit 0 of the error code: 0 = non-present page. Covers both user
// pushes past the mapped stack and kernel accesses to not-yet-grown
// user stack buffers passed into syscalls.
if ((errorCode & 1) == 0 && Sched::GetCurrentPid() >= 0
if ((errorCode & 1) == 0 && cpu != nullptr && cpu->currentSlot >= 0
&& Sched::GetCurrentPid() >= 0
&& Sched::TryGrowUserStack(cr2)) {
if (fromUser) asm volatile("swapgs");
return;