vm: implement private and shared address space mappings
whether a mapping is private or shared determines how the mapping is handled when a task is duplicated.
This commit is contained in:
+33
-2
@@ -706,6 +706,7 @@ kern_status_t address_space_map(
|
||||
struct vm_object *object,
|
||||
off_t object_offset,
|
||||
size_t length,
|
||||
vm_flags_t flags,
|
||||
vm_prot_t prot,
|
||||
virt_addr_t *out)
|
||||
{
|
||||
@@ -763,6 +764,7 @@ kern_status_t address_space_map(
|
||||
area->vma_space = root;
|
||||
area->vma_object = object;
|
||||
area->vma_prot = prot;
|
||||
area->vma_flags = flags;
|
||||
area->vma_object_offset = object_offset;
|
||||
area->vma_base = map_address;
|
||||
area->vma_limit = map_address + length - 1;
|
||||
@@ -1215,6 +1217,7 @@ static struct vm_area *area_duplicate(struct vm_area *area)
|
||||
}
|
||||
|
||||
out->vma_prot = area->vma_prot;
|
||||
out->vma_flags = area->vma_flags;
|
||||
out->vma_object_offset = area->vma_object_offset;
|
||||
out->vma_base = area->vma_base;
|
||||
out->vma_limit = area->vma_limit;
|
||||
@@ -1281,7 +1284,8 @@ static kern_status_t prepare_duplicate_areas(
|
||||
struct vm_object *src_vmo = tmp_area->vma_object;
|
||||
vm_object_lock(src_vmo);
|
||||
|
||||
struct vm_object *dest_vmo = NULL;
|
||||
struct vm_object *dest_vmo_link = NULL;
|
||||
struct vm_object *dest_vmo_cow = NULL;
|
||||
struct queue_entry *cur_entry
|
||||
= queue_first(&src_vmo->vo_mappings);
|
||||
|
||||
@@ -1312,6 +1316,13 @@ static kern_status_t prepare_duplicate_areas(
|
||||
continue;
|
||||
}
|
||||
|
||||
struct vm_object *dest_vmo = NULL;
|
||||
if (src_area->vma_flags & VM_SHARED) {
|
||||
dest_vmo = dest_vmo_link;
|
||||
} else {
|
||||
dest_vmo = dest_vmo_cow;
|
||||
}
|
||||
|
||||
if (!dest_vmo) {
|
||||
tracek("[%zx-%zx %x] creating COW duplicate of "
|
||||
"vmo %p",
|
||||
@@ -1319,7 +1330,18 @@ static kern_status_t prepare_duplicate_areas(
|
||||
src_area->vma_limit,
|
||||
src_area->vma_prot,
|
||||
src_vmo);
|
||||
dest_vmo = vm_object_duplicate_cow(src_vmo);
|
||||
|
||||
if (src_area->vma_flags & VM_SHARED) {
|
||||
dest_vmo_link = src_vmo;
|
||||
object_ref(&dest_vmo_link->vo_base);
|
||||
|
||||
dest_vmo = dest_vmo_link;
|
||||
} else {
|
||||
dest_vmo_cow = vm_object_duplicate_cow(
|
||||
src_vmo);
|
||||
dest_vmo = dest_vmo_cow;
|
||||
}
|
||||
|
||||
tracek("[%zx-%zx %x] created COW duplicate of "
|
||||
"vmo %p -> %p",
|
||||
src_area->vma_base,
|
||||
@@ -1329,11 +1351,20 @@ static kern_status_t prepare_duplicate_areas(
|
||||
dest_vmo);
|
||||
}
|
||||
|
||||
object_ref(&dest_vmo->vo_base);
|
||||
dest_area->vma_object = dest_vmo;
|
||||
update_area_pte_cow(src, dest, src_area);
|
||||
cur_entry = queue_next(cur_entry);
|
||||
}
|
||||
|
||||
if (dest_vmo_link) {
|
||||
object_unref(&dest_vmo_link->vo_base);
|
||||
}
|
||||
|
||||
if (dest_vmo_cow) {
|
||||
object_unref(&dest_vmo_cow->vo_base);
|
||||
}
|
||||
|
||||
vm_object_unlock(src_vmo);
|
||||
|
||||
cur_node = btree_next(cur_node);
|
||||
|
||||
Reference in New Issue
Block a user