Busy the map in vm_map_protect().
We are otherwise susceptible to a race with a concurrent vm_map_wire(), which may drop the map lock to fault pages into the object chain. In particular, vm_map_protect() will only copy newly writable wired pages into the top-level object when MAP_ENTRY_USER_WIRED is set, but vm_map_wire() only sets this flag after its fault loop. We may thus end up with a writable wired entry whose top-level object does not contain the entire range of pages. Reported and tested by: pho Reviewed by: kib MFC after: 1 week Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D10349
This commit is contained in:
parent
6c2b7edafe
commit
e1cb9d3747
@ -1965,6 +1965,14 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
|
||||
|
||||
vm_map_lock(map);
|
||||
|
||||
/*
|
||||
* Ensure that we are not concurrently wiring pages. vm_map_wire() may
|
||||
* need to fault pages into the map and will drop the map lock while
|
||||
* doing so, and the VM object may end up in an inconsistent state if we
|
||||
* update the protection on the map entry in between faults.
|
||||
*/
|
||||
vm_map_wait_busy(map);
|
||||
|
||||
VM_MAP_RANGE_CHECK(map, start, end);
|
||||
|
||||
if (vm_map_lookup_entry(map, start, &entry)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user