try to continue from walk() failing to allocate a page-table page

This commit is contained in:
Robert Morris 2019-07-02 11:45:06 -04:00
parent b27f275014
commit f59c1bf1d8
3 changed files with 17 additions and 8 deletions

View file

@ -185,9 +185,9 @@ pagetable_t uvmcreate(void);
void uvminit(pagetable_t, uchar *, uint); void uvminit(pagetable_t, uchar *, uint);
uint64 uvmalloc(pagetable_t, uint64, uint64); uint64 uvmalloc(pagetable_t, uint64, uint64);
uint64 uvmdealloc(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 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); void unmappages(pagetable_t, uint64, uint64, int);
uint64 walkaddr(pagetable_t, uint64); uint64 walkaddr(pagetable_t, uint64);
int copyout(pagetable_t, uint64, char *, uint64); int copyout(pagetable_t, uint64, char *, uint64);

View file

@ -119,8 +119,9 @@ walkaddr(pagetable_t pagetable, uint64 va)
// Create PTEs for virtual addresses starting at va that refer to // Create PTEs for virtual addresses starting at va that refer to
// physical addresses starting at pa. va and size might not // physical addresses starting at pa. va and size might not
// be page-aligned. // be page-aligned. Returns 0 on success, -1 if walk() couldn't
void // allocate a needed page-table page.
int
mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm) mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
{ {
uint64 a, last; uint64 a, last;
@ -130,7 +131,7 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
last = PGROUNDDOWN(va + size - 1); last = PGROUNDDOWN(va + size - 1);
for(;;){ for(;;){
if((pte = walk(pagetable, a, 1)) == 0) if((pte = walk(pagetable, a, 1)) == 0)
panic("mappages: walk"); return -1;
if(*pte & PTE_V) if(*pte & PTE_V)
panic("remap"); panic("remap");
*pte = PA2PTE(pa) | perm | PTE_V; *pte = PA2PTE(pa) | perm | PTE_V;
@ -139,6 +140,7 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
a += PGSIZE; a += PGSIZE;
pa += PGSIZE; pa += PGSIZE;
} }
return 0;
} }
// Remove mappings from a page table. The mappings in // Remove mappings from a page table. The mappings in
@ -222,7 +224,11 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
return 0; return 0;
} }
memset(mem, 0, PGSIZE); 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; return newsz;
} }
@ -293,7 +299,10 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
if((mem = kalloc()) == 0) if((mem = kalloc()) == 0)
goto err; goto err;
memmove(mem, (char*)pa, PGSIZE); 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; return 0;

View file

@ -1473,7 +1473,7 @@ sbrktest(void)
// can one grow address space to something big? // can one grow address space to something big?
a = sbrk(0); a = sbrk(0);
amt = (BIG) - (uint64)a; amt = BIG - (uint64)a;
p = sbrk(amt); p = sbrk(amt);
if (p != a) { if (p != a) {
printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n"); printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n");