Page fault handler now allocates new page tables

Rather than contantly checking if a page table exists before access, the fault handler will automatically allocate them as needed.
This commit is contained in:
2023-11-07 12:44:23 -06:00
parent 091830e508
commit 108e04a8f0
4 changed files with 106 additions and 25 deletions

View File

@@ -2,6 +2,9 @@
#include "stdio.h"
#include "x86/apic.h"
#include "platform/interrupts.h"
#include "mmgr.h"
#include "string.h"
#include "kernel.h"
#include <stdint.h>
@@ -14,6 +17,18 @@ struct interrupt_frame_t
uint32_t ss;
};
typedef struct page_fault_code_t
{
uint32_t present : 1;
uint32_t write : 1;
uint32_t usermode : 1;
uint32_t reserved : 1;
uint32_t inst_fetch : 1;
uint32_t pk : 1;
uint32_t shadow_stack : 1;
uint32_t padding : 25;
} page_fault_code_t;
void isr_generic(struct interrupt_frame_t *frame)
{
printf("Generic interrupt.\n");
@@ -46,6 +61,7 @@ void isr_gp_fault(struct interrupt_frame_t *frame, unsigned int error)
void isr_page_fault(struct interrupt_frame_t *frame, unsigned int error)
{
page_fault_code_t *code = &error;
uint32_t addr;
asm("mov %%cr2, %0"
: "=r"(addr));
@@ -55,8 +71,28 @@ void isr_page_fault(struct interrupt_frame_t *frame, unsigned int error)
"mov %%ax, %%fs; "
"mov %%ax, %%gs; " ::
: "ax");
printf("Exception: Page fault, code %08x, linear address %08x\n", error, addr);
asm("hlt");
if(code->usermode == 0
&& code->present == 0
&& addr >= 0xFFC00000
&& addr < 0xFFFFF000)
{
printf("Allocating new page table %08x within fault handler.\n", addr);
physaddr_t new_table = reserve_page();
if(new_table == ENOMEM)
{
kernel_panic("Out of memory while allocating page table.\n");
}
set_pte((void*)addr, 1, PAGE_PRESENT | PAGE_USERMODE | PAGE_RW, new_table);
asm volatile("mov %%cr3, %%eax;"
"mov %%eax, %%cr3" ::
: "eax", "memory");
memset((void*)(addr & ~0xFFF), 0, page_size);
}
else
{
printf("Exception: Page fault, code %08x, linear address %08x\n", error, addr);
kernel_panic("Unhandled page fault.\n");
}
}
void isr_double_fault(struct interrupt_frame_t *frame, unsigned int error)