kern

diff src/vm.c @ 76:0fe6eef16335

holy fuck, copy_on_write didn't actually do the copy!!!!
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 05 Nov 2011 04:53:46 +0200
parents d3601789d638
children
line diff
     1.1 --- a/src/vm.c	Sat Oct 15 08:07:09 2011 +0300
     1.2 +++ b/src/vm.c	Sat Nov 05 04:53:46 2011 +0200
     1.3 @@ -93,7 +93,7 @@
     1.4  	pglist[MEM_USER]->end = kmem_start_pg;
     1.5  	pglist[MEM_USER]->next = 0;
     1.6  
     1.7 -	/* temporaroly map something into every 1024th page of the kernel address
     1.8 +	/* temporarily map something into every 1024th page of the kernel address
     1.9  	 * space to force pre-allocation of all the kernel page-tables
    1.10  	 */
    1.11  	for(i=kmem_start_pg; i<pgtbl_base_pg; i+=1024) {
    1.12 @@ -607,7 +607,7 @@
    1.13  /* copy-on-write handler, called from pgfault above */
    1.14  static int copy_on_write(struct vm_page *page)
    1.15  {
    1.16 -	uint32_t newphys;
    1.17 +	int tmpvpg;
    1.18  	struct vm_page *newpage;
    1.19  	struct rbnode *vmnode;
    1.20  	struct process *p = get_current_proc();
    1.21 @@ -631,14 +631,19 @@
    1.22  	newpage->vpage = page->vpage;
    1.23  	newpage->flags = page->flags;
    1.24  
    1.25 -	if(!(newphys = alloc_phys_page())) {
    1.26 +	if(!(tmpvpg = pgalloc(1, MEM_KERNEL))) {
    1.27  		printf("copy_on_write: failed to allocate physical page\n");
    1.28  		/* XXX proper action: SIGSEGV */
    1.29  		return -1;
    1.30  	}
    1.31 -	newpage->ppage = ADDR_TO_PAGE(newphys);
    1.32 +	newpage->ppage = virt_to_phys_page(tmpvpg);
    1.33  	newpage->nref = 1;
    1.34  
    1.35 +	/* do the copy */
    1.36 +	memcpy((void*)PAGE_TO_ADDR(tmpvpg), (void*)PAGE_TO_ADDR(page->vpage), PGSIZE);
    1.37 +	unmap_page(tmpvpg);
    1.38 +	pgfree(tmpvpg, 1);
    1.39 +
    1.40  	/* set the new vm_page in the process vmmap */
    1.41  	vmnode = rb_findi(&p->vmmap, newpage->vpage);
    1.42  	assert(vmnode && vmnode->data == page);	/* shouldn't be able to fail */