diff --git a/kernel/proc.c b/kernel/proc.c index 417e30a..1774add 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -175,8 +175,8 @@ proc_pagetable(struct proc *p) void proc_freepagetable(pagetable_t pagetable, uint64 sz) { - uvmunmap(pagetable, TRAMPOLINE, PGSIZE, 0); - uvmunmap(pagetable, TRAPFRAME, PGSIZE, 0); + uvmunmap(pagetable, TRAMPOLINE, 1, 0); + uvmunmap(pagetable, TRAPFRAME, 1, 0); uvmfree(pagetable, sz); } diff --git a/kernel/vm.c b/kernel/vm.c index b48a022..92a5ff7 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -167,24 +167,23 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm) return 0; } -// Remove mappings from a page table. The mappings in -// the given range must exist. Optionally free the -// physical memory. +// Remove npages of mappings starting from va. va must be +// page-aligned. The mappings must exist. +// Optionally free the physical memory. void -uvmunmap(pagetable_t pagetable, uint64 va, uint64 size, int do_free) +uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free) { - uint64 a, last; + uint64 a; pte_t *pte; - a = PGROUNDDOWN(va); - last = PGROUNDDOWN(va + size - 1); - for(;;){ + if((va % PGSIZE) != 0) + panic("uvmunmap: not aligned"); + + for(a = va; a < va + npages*PGSIZE; a += PGSIZE){ if((pte = walk(pagetable, a, 0)) == 0) panic("uvmunmap: walk"); - if((*pte & PTE_V) == 0){ - printf("va=%p pte=%p\n", a, *pte); + if((*pte & PTE_V) == 0) panic("uvmunmap: not mapped"); - } if(PTE_FLAGS(*pte) == PTE_V) panic("uvmunmap: not a leaf"); if(do_free){ @@ -192,9 +191,6 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 size, int do_free) kfree((void*)pa); } *pte = 0; - if(a == last) - break; - a += PGSIZE; } } @@ -265,9 +261,10 @@ uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz) if(newsz >= oldsz) return oldsz; - uint64 newup = PGROUNDUP(newsz); - if(newup < PGROUNDUP(oldsz)) - uvmunmap(pagetable, newup, oldsz - newup, 1); + if(PGROUNDUP(newsz) < PGROUNDUP(oldsz)){ + int npages = (PGROUNDUP(oldsz) - PGROUNDUP(newsz)) / PGSIZE; + uvmunmap(pagetable, PGROUNDUP(newsz), npages, 1); + } return newsz; } @@ -298,7 +295,7 @@ void uvmfree(pagetable_t pagetable, uint64 sz) { if(sz > 0) - uvmunmap(pagetable, 0, sz, 1); + uvmunmap(pagetable, 0, PGROUNDUP(sz)/PGSIZE, 1); freewalk(pagetable); } @@ -334,7 +331,7 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) return 0; err: - uvmunmap(new, 0, i, 1); + uvmunmap(new, 0, i / PGSIZE, 1); return -1; }