mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-10 23:09:18 +00:00
scheduler: Fix page table switch for scheduler
The userspace process may map pages where the kernel has allocated data and cause a crash. This patch fixes this issue by having a separate IRQ handler which sets the kernel page table at the start of SchedulerInterruptHandler() and restores it in SchedulerHandlerStub() function.
This commit is contained in:
@ -556,7 +556,7 @@ namespace Tasking::Scheduler
|
||||
}
|
||||
}
|
||||
|
||||
nsa NIF void Custom::Schedule(CPU::TrapFrame *Frame)
|
||||
nsa NIF void Custom::Schedule(CPU::SchedulerFrame *Frame)
|
||||
{
|
||||
if (unlikely(StopScheduler))
|
||||
{
|
||||
@ -564,9 +564,6 @@ namespace Tasking::Scheduler
|
||||
return;
|
||||
}
|
||||
bool ProcessNotChanged = false;
|
||||
/* Restore kernel page table for safety reasons. */
|
||||
if (!SchedulerUpdateTrapFrame)
|
||||
KernelPageTable->Update();
|
||||
uint64_t SchedTmpTicks = TimeManager->GetCounter();
|
||||
this->LastTaskTicks.store(size_t(SchedTmpTicks - this->SchedulerTicks.load()));
|
||||
CPUData *CurrentCPU = GetCurrentCPU();
|
||||
@ -671,6 +668,13 @@ namespace Tasking::Scheduler
|
||||
CurrentCPU->CurrentProcess->State.store(TaskState::Running);
|
||||
CurrentCPU->CurrentThread->State.store(TaskState::Running);
|
||||
|
||||
if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE)
|
||||
CurrentCPU->CurrentThread->Registers.ppt = (uint64_t)(void *)CurrentCPU->CurrentProcess->PageTable;
|
||||
else
|
||||
CurrentCPU->CurrentThread->Registers.ppt = (uint64_t)(void *)KernelPageTable;
|
||||
|
||||
// if (!SchedulerUpdateTrapFrame) {} // TODO
|
||||
|
||||
*Frame = CurrentCPU->CurrentThread->Registers;
|
||||
|
||||
#ifdef a64
|
||||
@ -713,11 +717,9 @@ namespace Tasking::Scheduler
|
||||
}
|
||||
|
||||
this->SchedulerTicks.store(size_t(TimeManager->GetCounter() - SchedTmpTicks));
|
||||
if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE)
|
||||
CurrentCPU->CurrentProcess->PageTable->Update();
|
||||
}
|
||||
|
||||
nsa NIF void Custom::OnInterruptReceived(CPU::TrapFrame *Frame)
|
||||
nsa NIF void Custom::OnInterruptReceived(CPU::SchedulerFrame *Frame)
|
||||
{
|
||||
SmartCriticalSection(SchedulerLock);
|
||||
this->Schedule(Frame);
|
||||
|
@ -344,7 +344,7 @@ namespace Tasking
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Signal::HandleSignal(CPU::TrapFrame *tf, void *thread)
|
||||
bool Signal::HandleSignal(CPU::SchedulerFrame *tf, void *thread)
|
||||
{
|
||||
/* We don't want to do this in kernel mode */
|
||||
if (tf->cs != GDT_USER_CODE)
|
||||
|
Reference in New Issue
Block a user