kern
diff src/vm.c @ 52:fa65b4f45366
picking this up again, let's fix it
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 07 Aug 2011 06:42:00 +0300 |
parents | b1e8c8251884 |
children | 88a6c4e192f9 |
line diff
1.1 --- a/src/vm.c Mon Aug 01 06:45:29 2011 +0300 1.2 +++ b/src/vm.c Sun Aug 07 06:42:00 2011 +0300 1.3 @@ -1,12 +1,13 @@ 1.4 #include <stdio.h> 1.5 #include <string.h> 1.6 #include <inttypes.h> 1.7 +#include <assert.h> 1.8 +#include "config.h" 1.9 #include "vm.h" 1.10 -#include <stdio.h> 1.11 #include "intr.h" 1.12 #include "mem.h" 1.13 #include "panic.h" 1.14 - 1.15 +#include "proc.h" 1.16 1.17 #define IDMAP_START 0xa0000 1.18 1.19 @@ -37,7 +38,7 @@ 1.20 uint32_t get_fault_addr(void); 1.21 1.22 static void coalesce(struct page_range *low, struct page_range *mid, struct page_range *high); 1.23 -static void pgfault(int inum, struct intr_frame *frm); 1.24 +static void pgfault(int inum); 1.25 static struct page_range *alloc_node(void); 1.26 static void free_node(struct page_range *node); 1.27 1.28 @@ -457,11 +458,43 @@ 1.29 } 1.30 } 1.31 1.32 -static void pgfault(int inum, struct intr_frame *frm) 1.33 +static void pgfault(int inum) 1.34 { 1.35 + struct intr_frame *frm = get_intr_frame(); 1.36 + uint32_t fault_addr = get_fault_addr(); 1.37 + 1.38 + /* the fault occured in user space */ 1.39 + if(frm->esp < KMEM_START + 1) { 1.40 + int fault_page = ADDR_TO_PAGE(fault_addr); 1.41 + struct process *proc = get_current_proc(); 1.42 + assert(proc); 1.43 + 1.44 + printf("DBG: page fault in user space\n"); 1.45 + 1.46 + if(frm->err & PG_PRESENT) { 1.47 + /* it's not due to a missing page, just panic */ 1.48 + goto unhandled; 1.49 + } 1.50 + 1.51 + /* detect if it's an automatic stack growth deal */ 1.52 + if(fault_page < proc->stack_start_pg && proc->stack_start_pg - fault_page < USTACK_MAXGROW) { 1.53 + int num_pages = proc->stack_start_pg - fault_page; 1.54 + printf("growing user (%d) stack by %d pages\n", proc->id, num_pages); 1.55 + 1.56 + if(pgalloc_vrange(fault_page, num_pages) != fault_page) { 1.57 + printf("failed to allocate VM for stack growth\n"); 1.58 + /* TODO: in the future we'd SIGSEGV the process here, for now just panic */ 1.59 + goto unhandled; 1.60 + } 1.61 + proc->stack_start_pg = fault_page; 1.62 + 1.63 + return; 1.64 + } 1.65 + } 1.66 + 1.67 +unhandled: 1.68 printf("~~~~ PAGE FAULT ~~~~\n"); 1.69 - 1.70 - printf("fault address: %x\n", get_fault_addr()); 1.71 + printf("fault address: %x\n", fault_addr); 1.72 1.73 if(frm->err & PG_PRESENT) { 1.74 if(frm->err & 8) {