[zion] Use a separate stack for PF and GP faults in the kernel.

This commit is contained in:
Drew Galbraith 2023-08-01 23:11:12 -07:00
parent 259c64ef2a
commit e3a425e274
6 changed files with 28 additions and 2 deletions

View File

@ -93,4 +93,8 @@ void InitGdt() {
: "rax");
}
void SetIst1(uint64_t* ist1) {
gTaskStateSegment.ist1 = reinterpret_cast<uint64_t>(ist1);
}
void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; }

View File

@ -4,4 +4,6 @@
void InitGdt();
void SetIst1(uint64_t* ist1);
void SetRsp0(uint64_t rsp0);

View File

@ -30,12 +30,12 @@ struct InterruptDescriptor {
static InterruptDescriptor gIdt[256];
InterruptDescriptor CreateDescriptor(void isr(void)) {
InterruptDescriptor CreateDescriptor(void isr(void), uint8_t ist = 0) {
uint64_t offset = reinterpret_cast<uint64_t>(isr);
return InterruptDescriptor{
.offset_low = static_cast<uint16_t>(offset),
.selector = KERNEL_CS,
.ist = 0,
.ist = ist,
.flags = IDT_INTERRUPT_GATE,
.offset_medium = static_cast<uint16_t>(offset >> 16),
.offset_high = static_cast<uint32_t>(offset >> 32),
@ -192,4 +192,15 @@ void InitIdt() {
asm volatile("lidt %0" ::"m"(idtp));
}
void UpdateFaultHandlersToIst1() {
gIdt[13] = CreateDescriptor(isr_protection_fault, 1);
gIdt[14] = CreateDescriptor(isr_page_fault, 1);
InterruptDescriptorTablePointer idtp{
.size = sizeof(gIdt),
.base = reinterpret_cast<uint64_t>(gIdt),
};
asm volatile("lidt %0" ::"m"(idtp));
}
void RegisterPciPort(const glcr::RefPtr<Port>& port) { pci1_port = port; }

View File

@ -6,4 +6,6 @@
void InitIdt();
void UpdateFaultHandlersToIst1();
void RegisterPciPort(const glcr::RefPtr<Port>& port);

View File

@ -1,5 +1,6 @@
#include "memory/kernel_stack_manager.h"
#include "common/gdt.h"
#include "debug/debug.h"
#include "memory/paging_util.h"
@ -11,6 +12,8 @@ KernelStackManager* gKernelStackManager;
void KernelStackManager::Init() {
gKernelStackManager = new KernelStackManager();
SetIst1(gKernelStackManager->AllocateKernelStack());
}
KernelStackManager::KernelStackManager()

View File

@ -38,6 +38,10 @@ extern "C" void zion() {
dbgln("[boot] Init Kernel Stack Manager.");
KernelStackManager::Init();
// The KernelStackManager sets Ist1 as a part of initialization so we can use
// it now.
UpdateFaultHandlersToIst1();
dbgln("[boot] Init syscalls.");
InitSyscall();