diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2014-06-09 03:37:41 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2014-06-09 03:37:41 +0000 |
commit | 4648ba0a0f20a61d9fc0dcd26bbf00283d86e465 (patch) | |
tree | 3ecb1fd37dae1609bc6f8f9f07a7e4692fb26d7f /sys/vm/vm_mmap.c | |
parent | e41318fc7bffb6976fc37b318c9f2ee0adbc900c (diff) | |
download | src-4648ba0a0f20a61d9fc0dcd26bbf00283d86e465.tar.gz src-4648ba0a0f20a61d9fc0dcd26bbf00283d86e465.zip |
Make mmap(MAP_STACK) search for the available address space, similar
to !MAP_STACK mapping requests. For MAP_STACK | MAP_FIXED, clear any
mappings which could previously exist in the used range.
For this, teach vm_map_find() and vm_map_fixed() to handle
MAP_STACK_GROWS_DOWN or _UP cow flags, by calling a new
vm_map_stack_locked() helper, which is factored out from
vm_map_stack().
The side effect of the change is that MAP_STACK started obeying
MAP_ALIGNMENT and MAP_32BIT flags.
Reported by: rwatson
Reviewed by: alc
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Notes
Notes:
svn path=/head/; revision=267254
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r-- | sys/vm/vm_mmap.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 60aa6211981e..0fc5bb409a9a 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -1621,11 +1621,13 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, docow |= MAP_INHERIT_SHARE; if (writecounted) docow |= MAP_VN_WRITECOUNT; + if (flags & MAP_STACK) { + if (object != NULL) + return (EINVAL); + docow |= MAP_STACK_GROWS_DOWN; + } - if (flags & MAP_STACK) - rv = vm_map_stack(map, *addr, size, prot, maxprot, - docow | MAP_STACK_GROWS_DOWN); - else if (fitit) { + if (fitit) { if ((flags & MAP_ALIGNMENT_MASK) == MAP_ALIGNED_SUPER) findspace = VMFS_SUPER_SPACE; else if ((flags & MAP_ALIGNMENT_MASK) != 0) @@ -1638,9 +1640,10 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, flags & MAP_32BIT ? MAP_32BIT_MAX_ADDR : #endif 0, findspace, prot, maxprot, docow); - } else + } else { rv = vm_map_fixed(map, object, foff, *addr, size, - prot, maxprot, docow); + prot, maxprot, docow); + } if (rv == KERN_SUCCESS) { /* |