summaryrefslogtreecommitdiff
path: root/kernel/vm.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-07-01 17:46:06 -0400
committerRobert Morris <[email protected]>2019-07-01 17:46:06 -0400
commitabfe9999f447c15d904b3c11f32d4a22a45470a0 (patch)
treebdcf8264c9da666661b107157a6c634b86608ee2 /kernel/vm.c
parent18e76a6c47b0f62b2458430d4357f3eb68bfd759 (diff)
downloadxv6-labs-abfe9999f447c15d904b3c11f32d4a22a45470a0.tar.gz
xv6-labs-abfe9999f447c15d904b3c11f32d4a22a45470a0.tar.bz2
xv6-labs-abfe9999f447c15d904b3c11f32d4a22a45470a0.zip
have fork() fail, not panic, if not enough phys mem
Diffstat (limited to 'kernel/vm.c')
-rw-r--r--kernel/vm.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/kernel/vm.c b/kernel/vm.c
index 580669f..7d67464 100644
--- a/kernel/vm.c
+++ b/kernel/vm.c
@@ -273,7 +273,9 @@ uvmfree(pagetable_t pagetable, uint64 sz)
// its memory into a child's page table.
// Copies both the page table and the
// physical memory.
-void
+// returns 0 on success, -1 on failure.
+// frees any allocated pages on failure.
+int
uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
{
pte_t *pte;
@@ -289,10 +291,15 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
pa = PTE2PA(*pte);
flags = PTE_FLAGS(*pte);
if((mem = kalloc()) == 0)
- panic("uvmcopy: kalloc failed");
+ goto err;
memmove(mem, (char*)pa, PGSIZE);
mappages(new, i, PGSIZE, (uint64)mem, flags);
}
+ return 0;
+
+ err:
+ unmappages(new, 0, i, 1);
+ return -1;
}
// Copy from kernel to user.