fix: kernel concurrency, interrupt context, and user VA safety
This commit is contained in:
+12
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user