diff options
| -rw-r--r-- | kernel/defs.h | 4 | ||||
| -rw-r--r-- | kernel/vm.c | 19 | ||||
| -rw-r--r-- | user/usertests.c | 2 | 
3 files changed, 17 insertions, 8 deletions
| diff --git a/kernel/defs.h b/kernel/defs.h index 1c0b39a..bd89af0 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -185,9 +185,9 @@ pagetable_t     uvmcreate(void);  void            uvminit(pagetable_t, uchar *, uint);  uint64          uvmalloc(pagetable_t, uint64, uint64);  uint64          uvmdealloc(pagetable_t, uint64, uint64); -int            uvmcopy(pagetable_t, pagetable_t, uint64); +int             uvmcopy(pagetable_t, pagetable_t, uint64);  void            uvmfree(pagetable_t, uint64); -void            mappages(pagetable_t, uint64, uint64, uint64, int); +int             mappages(pagetable_t, uint64, uint64, uint64, int);  void            unmappages(pagetable_t, uint64, uint64, int);  uint64          walkaddr(pagetable_t, uint64);  int             copyout(pagetable_t, uint64, char *, uint64); diff --git a/kernel/vm.c b/kernel/vm.c index d5ff594..bdb53c2 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -119,8 +119,9 @@ walkaddr(pagetable_t pagetable, uint64 va)  // Create PTEs for virtual addresses starting at va that refer to  // physical addresses starting at pa. va and size might not -// be page-aligned. -void +// be page-aligned. Returns 0 on success, -1 if walk() couldn't +// allocate a needed page-table page. +int  mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)  {    uint64 a, last; @@ -130,7 +131,7 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)    last = PGROUNDDOWN(va + size - 1);    for(;;){      if((pte = walk(pagetable, a, 1)) == 0) -      panic("mappages: walk"); +      return -1;      if(*pte & PTE_V)        panic("remap");      *pte = PA2PTE(pa) | perm | PTE_V; @@ -139,6 +140,7 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)      a += PGSIZE;      pa += PGSIZE;    } +  return 0;  }  // Remove mappings from a page table. The mappings in @@ -222,7 +224,11 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)        return 0;      }      memset(mem, 0, PGSIZE); -    mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U); +    if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0){ +      kfree(mem); +      uvmdealloc(pagetable, a, oldsz); +      return 0; +    }    }    return newsz;  } @@ -293,7 +299,10 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)      if((mem = kalloc()) == 0)        goto err;      memmove(mem, (char*)pa, PGSIZE); -    mappages(new, i, PGSIZE, (uint64)mem, flags); +    if(mappages(new, i, PGSIZE, (uint64)mem, flags) != 0){ +      kfree(mem); +      goto err; +    }    }    return 0; diff --git a/user/usertests.c b/user/usertests.c index 0aafe73..ef70bfb 100644 --- a/user/usertests.c +++ b/user/usertests.c @@ -1473,7 +1473,7 @@ sbrktest(void)    // can one grow address space to something big?    a = sbrk(0); -  amt = (BIG) - (uint64)a; +  amt = BIG - (uint64)a;    p = sbrk(amt);    if (p != a) {      printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); | 
