diff options
author | Mole Shang <[email protected]> | 2024-02-11 17:51:28 +0800 |
---|---|---|
committer | Mole Shang <[email protected]> | 2024-02-11 17:51:28 +0800 |
commit | 4a6593f1a6f666c618d303a4858c4c6d31b41c63 (patch) | |
tree | 29d5302aec4e0f3c34a70baa9fb83c0bb35dbf7c /kernel/vm.c | |
parent | 2fe04bc8faa4bf737a86c36a8017473e84814f3b (diff) | |
download | xv6-labs-4a6593f1a6f666c618d303a4858c4c6d31b41c63.tar.gz xv6-labs-4a6593f1a6f666c618d303a4858c4c6d31b41c63.tar.bz2 xv6-labs-4a6593f1a6f666c618d303a4858c4c6d31b41c63.zip |
lab cow: finishcow
Diffstat (limited to 'kernel/vm.c')
-rw-r--r-- | kernel/vm.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/kernel/vm.c b/kernel/vm.c index 9c17fe7..11f9e0a 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -315,20 +315,26 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) pte_t *pte; uint64 pa, i; uint flags; - char *mem; + // char *mem; for(i = 0; i < sz; i += PGSIZE){ if((pte = walk(old, i, 0)) == 0) panic("uvmcopy: pte should exist"); if((*pte & PTE_V) == 0) panic("uvmcopy: page not present"); - pa = PTE2PA(*pte); - flags = PTE_FLAGS(*pte); + // do not do the actual copy, just increase the refcnt and mark pages readonly COW + /* if((mem = kalloc()) == 0) goto err; memmove(mem, (char*)pa, PGSIZE); - if(mappages(new, i, PGSIZE, (uint64)mem, flags) != 0){ - kfree(mem); + */ + *pte &= ~PTE_W; + *pte |= PTE_C; + pa = PTE2PA(*pte); + refcnt_inc(pa); + flags = PTE_FLAGS(*pte); + if(mappages(new, i, PGSIZE, (uint64)pa, flags) != 0){ + // kfree(mem); goto err; } } @@ -359,17 +365,24 @@ int copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len) { uint64 n, va0, pa0; - pte_t *pte; + // pte_t *pte; while(len > 0){ va0 = PGROUNDDOWN(dstva); - if(va0 >= MAXVA) + + if(cow_handler(pagetable, va0) < 0) return -1; + + /* pte = walk(pagetable, va0, 0); if(pte == 0 || (*pte & PTE_V) == 0 || (*pte & PTE_U) == 0 || (*pte & PTE_W) == 0) return -1; pa0 = PTE2PA(*pte); + */ + pa0 = walkaddr(pagetable, va0); + if(pa0 == 0) + return -1; n = PGSIZE - (dstva - va0); if(n > len) n = len; |