Do not drop vm_map lock between doing vm_map_remove() and vm_map_insert().
For this, introduce vm_map_fixed() that does that for MAP_FIXED case. Dropping the lock allowed for parallel thread to occupy the freed space. Reported by: Tijl Coosemans <tijl ulyssis org> Reviewed by: alc Approved by: re (kensmith) MFC after: 2 weeks
This commit is contained in:
parent
e23c502c5b
commit
77766ce03f
@ -155,6 +155,22 @@ static void vmspace_zdtor(void *mem, int size, void *arg);
|
||||
#define PROC_VMSPACE_LOCK(p) do { } while (0)
|
||||
#define PROC_VMSPACE_UNLOCK(p) do { } while (0)
|
||||
|
||||
/*
|
||||
* VM_MAP_RANGE_CHECK: [ internal use only ]
|
||||
*
|
||||
* Asserts that the starting and ending region
|
||||
* addresses fall within the valid range of the map.
|
||||
*/
|
||||
#define VM_MAP_RANGE_CHECK(map, start, end) \
|
||||
{ \
|
||||
if (start < vm_map_min(map)) \
|
||||
start = vm_map_min(map); \
|
||||
if (end > vm_map_max(map)) \
|
||||
end = vm_map_max(map); \
|
||||
if (start > end) \
|
||||
start = end; \
|
||||
}
|
||||
|
||||
void
|
||||
vm_map_startup(void)
|
||||
{
|
||||
@ -1145,6 +1161,25 @@ vm_map_findspace(vm_map_t map, vm_offset_t start, vm_size_t length,
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
vm_map_fixed(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
||||
vm_offset_t *addr /* IN/OUT */, vm_size_t length, vm_prot_t prot,
|
||||
vm_prot_t max, int cow)
|
||||
{
|
||||
vm_offset_t start, end;
|
||||
int result;
|
||||
|
||||
start = *addr;
|
||||
vm_map_lock(map);
|
||||
end = start + length;
|
||||
VM_MAP_RANGE_CHECK(map, start, end);
|
||||
(void) vm_map_delete(map, start, end);
|
||||
result = vm_map_insert(map, object, offset, start, end, prot,
|
||||
max, cow);
|
||||
vm_map_unlock(map);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* vm_map_find finds an unallocated region in the target address
|
||||
* map with the given length. The search is defined to be
|
||||
@ -1354,22 +1389,6 @@ _vm_map_clip_end(vm_map_t map, vm_map_entry_t entry, vm_offset_t end)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* VM_MAP_RANGE_CHECK: [ internal use only ]
|
||||
*
|
||||
* Asserts that the starting and ending region
|
||||
* addresses fall within the valid range of the map.
|
||||
*/
|
||||
#define VM_MAP_RANGE_CHECK(map, start, end) \
|
||||
{ \
|
||||
if (start < vm_map_min(map)) \
|
||||
start = vm_map_min(map); \
|
||||
if (end > vm_map_max(map)) \
|
||||
end = vm_map_max(map); \
|
||||
if (start > end) \
|
||||
start = end; \
|
||||
}
|
||||
|
||||
/*
|
||||
* vm_map_submap: [ kernel use only ]
|
||||
*
|
||||
|
@ -333,6 +333,7 @@ boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t
|
||||
vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t);
|
||||
int vm_map_delete (vm_map_t, vm_offset_t, vm_offset_t);
|
||||
int vm_map_find (vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t, boolean_t, vm_prot_t, vm_prot_t, int);
|
||||
int vm_map_fixed (vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int);
|
||||
int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_offset_t *);
|
||||
int vm_map_inherit (vm_map_t, vm_offset_t, vm_offset_t, vm_inherit_t);
|
||||
void vm_map_init (struct vm_map *, vm_offset_t, vm_offset_t);
|
||||
|
@ -1341,7 +1341,6 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
||||
if (*addr != trunc_page(*addr))
|
||||
return (EINVAL);
|
||||
fitit = FALSE;
|
||||
(void) vm_map_remove(map, *addr, *addr + size);
|
||||
}
|
||||
/*
|
||||
* Lookup/allocate object.
|
||||
@ -1400,8 +1399,11 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
||||
if (flags & MAP_STACK)
|
||||
rv = vm_map_stack(map, *addr, size, prot, maxprot,
|
||||
docow | MAP_STACK_GROWS_DOWN);
|
||||
else if (fitit)
|
||||
rv = vm_map_find(map, object, foff, addr, size, TRUE,
|
||||
prot, maxprot, docow);
|
||||
else
|
||||
rv = vm_map_find(map, object, foff, addr, size, fitit,
|
||||
rv = vm_map_fixed(map, object, foff, addr, size,
|
||||
prot, maxprot, docow);
|
||||
|
||||
if (rv != KERN_SUCCESS) {
|
||||
|
Loading…
Reference in New Issue
Block a user