vm.c
// Given a parent process's page table, create a copy
// of it for a child.
Given a parent process's page table, create a copy
of it for a child.
Given a parent process ' s page table create a copy of it for a child .
pde_t*
copyuvm(pde_t *pgdir, uint sz)
{
  pde_t *d;
  pte_t *pte, *pte2;
  uint pa, i, flags;
  char *mem;
  if((d = setupkvm()) == 0)
    return 0;
  for(i = 0; i < sz; i += PGSIZE){
    if((pte = walkpgdir(pgdir, (void *) i, 0)) == 0)
      panic("copyuvm: pte should exist");
    pa = PTE_ADDR(*pte);
    flags = PTE_FLAGS(*pte);
    if(!(*pte & PTE_SWAPPED)) {
      if((mem = kalloc()) == 0)
        goto bad;
      memmove(mem, (char*)P2V(pa), PGSIZE);
      if(mappages(d, (void*)i, PGSIZE, V2P(mem), flags) < 0) {
        kfree(mem);
        goto bad;
      }
    } 
    else {
      pte2 = walkpgdir(d, (void*)i, 1);
      *pte2 = pa | flags; 
    }
  }
  return d;
bad:
  freevm(d);
  return 0;
}
pde_t * copyuvm ( pde_t * pgdir , uint sz ) { pde_t * d ; pte_t * pte , * pte2 ; uint pa , i , flags ; char * mem ; if ( ( d = setupkvm ( ) ) == 0 ) return 0 ; for ( i = 0 ; i < sz ; i += PGSIZE ) { if ( ( pte = walkpgdir ( pgdir , ( void * ) i , 0 ) ) == 0 ) panic ( " " ) ; pa = PTE_ADDR ( * pte ) ; flags = PTE_FLAGS ( * pte ) ; if ( ! ( * pte & PTE_SWAPPED ) ) { if ( ( mem = kalloc ( ) ) == 0 ) goto bad ; memmove ( mem , ( char * ) P2V ( pa ) , PGSIZE ) ; if ( mappages ( d , ( void * ) i , PGSIZE , V2P ( mem ) , flags ) < 0 ) { kfree ( mem ) ; goto bad ; } } else { pte2 = walkpgdir ( d , ( void * ) i , 1 ) ; * pte2 = pa | flags ; } } return d ; bad : freevm ( d ) ; return 0 ; }
Given a parent process's page table, create a copy
of it for a child.
Given a parent process ' s page table create a copy of it for a child .