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) {