diff --git a/kernel/include/process.h b/kernel/include/process.h index a4636ed..dda4fbc 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -3,6 +3,7 @@ typedef struct process_st process_t; #include #include #include +#include #include #include #include @@ -62,3 +63,4 @@ void procmm_print_map(procmm_mmap_t *map); procmm_area_t *procmm_map(procmm_mmap_t *map, uintptr_t start, uintptr_t end, uint64_t flags); void procmm_unmap(procmm_area_t *a); uintptr_t procmm_setup(process_t *proc); +registers_t *procmm_page_fault(registers_t *r); diff --git a/kernel/mem/vmm.c b/kernel/mem/vmm.c index fa4ff56..95564de 100644 --- a/kernel/mem/vmm.c +++ b/kernel/mem/vmm.c @@ -4,6 +4,7 @@ #include #include #include +#include #define STRIP_FLAGS(addr) ((void *)(((uintptr_t)(addr)) & ~PAGE_FLAGS_MASK)) @@ -169,6 +170,13 @@ size_t vmm_p4_memset(page_table *P4, void *s, int c, size_t n) registers_t *page_fault_handler(registers_t *r) { + if(get_current_process()) + { + registers_t *ret = procmm_page_fault(r); + if(ret) + return ret; + } + debug("\n ===== PAGE FAULT =====\n"); debug("Instruction at:%x tried to", r->rip); if(r->err_code & 0x2) diff --git a/kernel/proc/procmm.c b/kernel/proc/procmm.c index 625e086..f225fc0 100644 --- a/kernel/proc/procmm.c +++ b/kernel/proc/procmm.c @@ -1,6 +1,9 @@ #include #include #include +#include +#include +#include procmm_mmap_t *procmm_new_map(process_t *proc, procmm_mmap_t *src) { @@ -112,3 +115,28 @@ uintptr_t procmm_setup(process_t *proc) return brk_start; } + +registers_t *procmm_page_fault(registers_t *r) +{ + procmm_mmap_t *map = get_current_process()->mmap; + uintptr_t addr = read_cr2(); + + // We don't want to handle stuff in the kernel + if(addr >= KERNEL_OFFSET) + return 0; + + // Check if we're close to the stack + if(map->stack) + { + if(map->stack->start <= addr + PAGE_SIZE) + { + debug("Increase user stack\n"); + map->stack->start = map->stack->start - PAGE_SIZE; + vmm_set_page(map->P4, map->stack->start, pmm_alloc(), PAGE_PRESENT | PAGE_WRITE | PAGE_USER); + return r; + } + } + + // If we reach this point, procmm couldn't handle the page fault + return 0; +}