summaryrefslogtreecommitdiff
path: root/kernel/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vm.c')
-rw-r--r--kernel/vm.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/kernel/vm.c b/kernel/vm.c
index be7d042..08859ae 100644
--- a/kernel/vm.c
+++ b/kernel/vm.c
@@ -182,6 +182,7 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
{
uint64 a;
pte_t *pte;
+ int cow_pg = 0;
if((va % PGSIZE) != 0)
panic("uvmunmap: not aligned");
@@ -192,10 +193,11 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
if((*pte & PTE_V) == 0) {
printf("va=%p pte=%p\n", a, *pte);
panic("uvmunmap: not mapped");
+ cow_pg = 1;
}
if(PTE_FLAGS(*pte) == PTE_V)
panic("uvmunmap: not a leaf");
- if(do_free){
+ if(do_free && !cow_pg){
uint64 pa = PTE2PA(*pte);
kfree((void*)pa);
}
@@ -315,14 +317,14 @@ uvmfree(pagetable_t pagetable, uint64 sz)
// returns 0 on success, -1 on failure.
// frees any allocated pages on failure.
int
-uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
+uvmcopy(pagetable_t old, pagetable_t new, uint64 start, uint64 sz)
{
pte_t *pte;
uint64 pa, i;
uint flags;
// char *mem;
- for(i = 0; i < sz; i += PGSIZE){
+ for(i = start; i < start+sz; i += PGSIZE){
if((pte = walk(old, i, 0)) == 0)
panic("uvmcopy: pte should exist");
if((*pte & PTE_V) == 0)