kernel/vm.c
uint64
uvmalloc(pagetable_t pagetable, pagetable_t kpagetable, uint64 oldsz, uint64 newsz)
{
  char *mem;
  uint64 a;

  if(newsz < oldsz)
    return oldsz;

  oldsz = PGROUNDUP(oldsz);
  for(a = oldsz; a < newsz; a += PGSIZE){
    mem = kalloc();
    if(mem == NULL){
      uvmdealloc(pagetable, kpagetable, a, oldsz);
      return 0;
    }
    memset(mem, 0, PGSIZE);
    if (mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0) {
      kfree(mem);
      uvmdealloc(pagetable, kpagetable, a, oldsz);
      return 0;
    }
    if (mappages(kpagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R) != 0){
      int npages = (a - oldsz) / PGSIZE;
      vmunmap(pagetable, oldsz, npages + 1, 1);   // plus the page allocated above.
      vmunmap(kpagetable, oldsz, npages, 0);
      return 0;
    }
  }
  return newsz;
}
// Allocate PTEs and physical memory to grow process from oldsz to
// newsz, which need not be page aligned.  Returns new size or 0 on error.
Allocate PTEs and physical memory to grow process from oldsz to
newsz, which need not be page aligned.  Returns new size or 0 on error.
Allocate PTEs and physical memory to grow process from oldsz to newsz which need not be page aligned . Returns new size or 0 on error .
uint64
uvmalloc(pagetable_t pagetable, pagetable_t kpagetable, uint64 oldsz, uint64 newsz)
{
  char *mem;
  uint64 a;
  if(newsz < oldsz)
    return oldsz;
  oldsz = PGROUNDUP(oldsz);
  for(a = oldsz; a < newsz; a += PGSIZE){
    mem = kalloc();
    if(mem == NULL){
      uvmdealloc(pagetable, kpagetable, a, oldsz);
      return 0;
    }
    memset(mem, 0, PGSIZE);
    if (mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0) {
      kfree(mem);
      uvmdealloc(pagetable, kpagetable, a, oldsz);
      return 0;
    }
    if (mappages(kpagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R) != 0){
      int npages = (a - oldsz) / PGSIZE;
      vmunmap(pagetable, oldsz, npages + 1, 1);   
      vmunmap(kpagetable, oldsz, npages, 0);
      return 0;
    }
  }
  return newsz;
}
uint64 uvmalloc ( pagetable_t pagetable , pagetable_t kpagetable , uint64 oldsz , uint64 newsz ) { char * mem ; uint64 a ; if ( newsz < oldsz ) return oldsz ; oldsz = PGROUNDUP ( oldsz ) ; for ( a = oldsz ; a < newsz ; a += PGSIZE ) { mem = kalloc ( ) ; if ( mem == NULL ) { uvmdealloc ( pagetable , kpagetable , a , oldsz ) ; return 0 ; } memset ( mem , 0 , PGSIZE ) ; if ( mappages ( pagetable , a , PGSIZE , ( uint64 ) mem , PTE_W | PTE_X | PTE_R | PTE_U ) != 0 ) { kfree ( mem ) ; uvmdealloc ( pagetable , kpagetable , a , oldsz ) ; return 0 ; } if ( mappages ( kpagetable , a , PGSIZE , ( uint64 ) mem , PTE_W | PTE_X | PTE_R ) != 0 ) { int npages = ( a - oldsz ) / PGSIZE ; vmunmap ( pagetable , oldsz , npages + 1 , 1 ) ; vmunmap ( kpagetable , oldsz , npages , 0 ) ; return 0 ; } } return newsz ; }
Allocate PTEs and physical memory to grow process from oldsz to
newsz, which need not be page aligned.
Allocate PTEs and physical memory to grow process from oldsz to newsz which need not be page aligned .
// plus the page allocated above.