summaryrefslogtreecommitdiff
path: root/vm/vm_pageout.c
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-16 12:54:41 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-09-14 14:45:05 +0200
commit22778b589af94261c2d8d0665220770d0b56d1a8 (patch)
tree97bdb1c058f030d30dfe0d566630010572a4fb35 /vm/vm_pageout.c
parent81747ac6d3e846d1955edaa94dee9065e541b7d8 (diff)
vm: fix locking issues
Avoid accessing fields of `vm_object' objects without having it locked. These problems have been found using a code transformation done by Coccinelle that instrumented all accesses with a runtime check, and manual inspection. * vm/memory_object.c (memory_object_data_supply): Avoid accessing fields without the lock. * vm/vm_fault.c (vm_fault_page): Likewise. * vm/vm_map.c (vm_map_submap): Properly lock `object'. (vm_map_copy_overwrite): Avoid accessing fields without the lock. (vm_map_copyin): Lock `src_object'. * vm/vm_object.c (_vm_object_setup): Likewise. (vm_object_allocate): Likewise. (vm_object_terminate): Avoid accessing fields without the lock. (vm_object_copy_slowly): Lock `new_object'. (vm_object_copy_delayed): Lock `src_object' earlier, lock `new_copy'. (vm_object_shadow): Lock `result'. (vm_object_enter): Properly lock `object'. Avoid accessing fields without the lock. * vm/vm_pageout.c (vm_pageout_setup): Properly lock `old_object'.
Diffstat (limited to 'vm/vm_pageout.c')
-rw-r--r--vm/vm_pageout.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/vm/vm_pageout.c b/vm/vm_pageout.c
index 51a6a0d..b676c7b 100644
--- a/vm/vm_pageout.c
+++ b/vm/vm_pageout.c
@@ -252,6 +252,8 @@ vm_pageout_setup(
vm_object_unlock(new_object);
}
+ vm_object_lock(old_object);
+
if (flush) {
/*
* Create a place-holder page where the old one was,
@@ -262,7 +264,6 @@ vm_pageout_setup(
== VM_PAGE_NULL)
vm_page_more_fictitious();
- vm_object_lock(old_object);
vm_page_lock_queues();
vm_page_remove(m);
vm_page_unlock_queues();
@@ -281,8 +282,6 @@ vm_pageout_setup(
VM_EXTERNAL_STATE_EXISTS);
#endif /* MACH_PAGEMAP */
- vm_object_unlock(old_object);
-
vm_object_lock(new_object);
/*
@@ -305,7 +304,6 @@ vm_pageout_setup(
*/
vm_page_copy(m, new_m);
- vm_object_lock(old_object);
m->dirty = FALSE;
pmap_clear_modify(m->phys_addr);
@@ -328,8 +326,6 @@ vm_pageout_setup(
VM_EXTERNAL_STATE_EXISTS);
#endif /* MACH_PAGEMAP */
- vm_object_unlock(old_object);
-
vm_object_lock(new_object);
/*
@@ -383,6 +379,7 @@ vm_pageout_setup(
*/
vm_object_unlock(new_object);
+ vm_object_unlock(old_object);
/*
* Return the placeholder page to simplify cleanup.