summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>1999-06-17 00:39:26 +0000
committeralc <alc@FreeBSD.org>1999-06-17 00:39:26 +0000
commit9fb63b7080a91371dcc62c3cf600d5828dd4d2b3 (patch)
tree5c6b43e1b86c4d51c152cb4117bead42b91521f2 /sys/vm/vm_map.c
parentbdb6bd306668664987b44d9b695607419b006dd2 (diff)
downloadFreeBSD-src-9fb63b7080a91371dcc62c3cf600d5828dd4d2b3.zip
FreeBSD-src-9fb63b7080a91371dcc62c3cf600d5828dd4d2b3.tar.gz
Move vm_map_stack and vm_map_growstack after the definition
of the vm_map_clip_end macro. (The next commit will modify vm_map_stack and vm_map_growstack to use vm_map_clip_end.)
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r--sys/vm/vm_map.c408
1 files changed, 204 insertions, 204 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index e8dc45c..f20a29e 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.c,v 1.166 1999/06/12 23:10:38 alc Exp $
+ * $Id: vm_map.c,v 1.167 1999/06/17 00:27:39 alc Exp $
*/
/*
@@ -556,209 +556,6 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
return (KERN_SUCCESS);
}
-int
-vm_map_stack (vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize,
- vm_prot_t prot, vm_prot_t max, int cow)
-{
- vm_map_entry_t prev_entry;
- vm_map_entry_t new_stack_entry;
- vm_size_t init_ssize;
- int rv;
-
- if (VM_MIN_ADDRESS > 0 && addrbos < VM_MIN_ADDRESS)
- return (KERN_NO_SPACE);
-
- if (max_ssize < SGROWSIZ)
- init_ssize = max_ssize;
- else
- init_ssize = SGROWSIZ;
-
- vm_map_lock(map);
-
- /* If addr is already mapped, no go */
- if (vm_map_lookup_entry(map, addrbos, &prev_entry)) {
- vm_map_unlock(map);
- return (KERN_NO_SPACE);
- }
-
- /* If we can't accomodate max_ssize in the current mapping,
- * no go. However, we need to be aware that subsequent user
- * mappings might map into the space we have reserved for
- * stack, and currently this space is not protected.
- *
- * Hopefully we will at least detect this condition
- * when we try to grow the stack.
- */
- if ((prev_entry->next != &map->header) &&
- (prev_entry->next->start < addrbos + max_ssize)) {
- vm_map_unlock(map);
- return (KERN_NO_SPACE);
- }
-
- /* We initially map a stack of only init_ssize. We will
- * grow as needed later. Since this is to be a grow
- * down stack, we map at the top of the range.
- *
- * Note: we would normally expect prot and max to be
- * VM_PROT_ALL, and cow to be 0. Possibly we should
- * eliminate these as input parameters, and just
- * pass these values here in the insert call.
- */
- rv = vm_map_insert(map, NULL, 0, addrbos + max_ssize - init_ssize,
- addrbos + max_ssize, prot, max, cow);
-
- /* Now set the avail_ssize amount */
- if (rv == KERN_SUCCESS){
- new_stack_entry = prev_entry->next;
- if (new_stack_entry->end != addrbos + max_ssize ||
- new_stack_entry->start != addrbos + max_ssize - init_ssize)
- panic ("Bad entry start/end for new stack entry");
- else
- new_stack_entry->avail_ssize = max_ssize - init_ssize;
- }
-
- vm_map_unlock(map);
- return (rv);
-}
-
-/* Attempts to grow a vm stack entry. Returns KERN_SUCCESS if the
- * desired address is already mapped, or if we successfully grow
- * the stack. Also returns KERN_SUCCESS if addr is outside the
- * stack range (this is strange, but preserves compatibility with
- * the grow function in vm_machdep.c).
- */
-int
-vm_map_growstack (struct proc *p, vm_offset_t addr)
-{
- vm_map_entry_t prev_entry;
- vm_map_entry_t stack_entry;
- vm_map_entry_t new_stack_entry;
- struct vmspace *vm = p->p_vmspace;
- vm_map_t map = &vm->vm_map;
- vm_offset_t end;
- int grow_amount;
- int rv;
- int is_procstack;
-Retry:
- vm_map_lock_read(map);
-
- /* If addr is already in the entry range, no need to grow.*/
- if (vm_map_lookup_entry(map, addr, &prev_entry)) {
- vm_map_unlock_read(map);
- return (KERN_SUCCESS);
- }
-
- if ((stack_entry = prev_entry->next) == &map->header) {
- vm_map_unlock_read(map);
- return (KERN_SUCCESS);
- }
- if (prev_entry == &map->header)
- end = stack_entry->start - stack_entry->avail_ssize;
- else
- end = prev_entry->end;
-
- /* This next test mimics the old grow function in vm_machdep.c.
- * It really doesn't quite make sense, but we do it anyway
- * for compatibility.
- *
- * If not growable stack, return success. This signals the
- * caller to proceed as he would normally with normal vm.
- */
- if (stack_entry->avail_ssize < 1 ||
- addr >= stack_entry->start ||
- addr < stack_entry->start - stack_entry->avail_ssize) {
- vm_map_unlock_read(map);
- return (KERN_SUCCESS);
- }
-
- /* Find the minimum grow amount */
- grow_amount = roundup (stack_entry->start - addr, PAGE_SIZE);
- if (grow_amount > stack_entry->avail_ssize) {
- vm_map_unlock_read(map);
- return (KERN_NO_SPACE);
- }
-
- /* If there is no longer enough space between the entries
- * nogo, and adjust the available space. Note: this
- * should only happen if the user has mapped into the
- * stack area after the stack was created, and is
- * probably an error.
- *
- * This also effectively destroys any guard page the user
- * might have intended by limiting the stack size.
- */
- if (grow_amount > stack_entry->start - end) {
- if (vm_map_lock_upgrade(map))
- goto Retry;
-
- stack_entry->avail_ssize = stack_entry->start - end;
-
- vm_map_unlock(map);
- return (KERN_NO_SPACE);
- }
-
- is_procstack = addr >= (vm_offset_t)vm->vm_maxsaddr;
-
- /* If this is the main process stack, see if we're over the
- * stack limit.
- */
- if (is_procstack && (vm->vm_ssize + grow_amount >
- p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
- vm_map_unlock_read(map);
- return (KERN_NO_SPACE);
- }
-
- /* Round up the grow amount modulo SGROWSIZ */
- grow_amount = roundup (grow_amount, SGROWSIZ);
- if (grow_amount > stack_entry->avail_ssize) {
- grow_amount = stack_entry->avail_ssize;
- }
- if (is_procstack && (vm->vm_ssize + grow_amount >
- p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
- grow_amount = p->p_rlimit[RLIMIT_STACK].rlim_cur -
- vm->vm_ssize;
- }
-
- if (vm_map_lock_upgrade(map))
- goto Retry;
-
- /* Get the preliminary new entry start value */
- addr = stack_entry->start - grow_amount;
-
- /* If this puts us into the previous entry, cut back our growth
- * to the available space. Also, see the note above.
- */
- if (addr < end) {
- stack_entry->avail_ssize = stack_entry->start - end;
- addr = end;
- }
-
- rv = vm_map_insert(map, NULL, 0, addr, stack_entry->start,
- stack_entry->protection,
- stack_entry->max_protection,
- 0);
-
- /* Adjust the available stack space by the amount we grew. */
- if (rv == KERN_SUCCESS) {
- new_stack_entry = prev_entry->next;
- if (new_stack_entry->end != stack_entry->start ||
- new_stack_entry->start != addr)
- panic ("Bad stack grow start/end in new stack entry");
- else {
- new_stack_entry->avail_ssize = stack_entry->avail_ssize -
- (new_stack_entry->end -
- new_stack_entry->start);
- if (is_procstack)
- vm->vm_ssize += new_stack_entry->end -
- new_stack_entry->start;
- }
- }
-
- vm_map_unlock(map);
- return (rv);
-
-}
-
/*
* Find sufficient space for `length' bytes in the given map, starting at
* `start'. The map must be locked. Returns 0 on success, 1 on no space.
@@ -2336,6 +2133,209 @@ vmspace_fork(vm1)
return (vm2);
}
+int
+vm_map_stack (vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize,
+ vm_prot_t prot, vm_prot_t max, int cow)
+{
+ vm_map_entry_t prev_entry;
+ vm_map_entry_t new_stack_entry;
+ vm_size_t init_ssize;
+ int rv;
+
+ if (VM_MIN_ADDRESS > 0 && addrbos < VM_MIN_ADDRESS)
+ return (KERN_NO_SPACE);
+
+ if (max_ssize < SGROWSIZ)
+ init_ssize = max_ssize;
+ else
+ init_ssize = SGROWSIZ;
+
+ vm_map_lock(map);
+
+ /* If addr is already mapped, no go */
+ if (vm_map_lookup_entry(map, addrbos, &prev_entry)) {
+ vm_map_unlock(map);
+ return (KERN_NO_SPACE);
+ }
+
+ /* If we can't accomodate max_ssize in the current mapping,
+ * no go. However, we need to be aware that subsequent user
+ * mappings might map into the space we have reserved for
+ * stack, and currently this space is not protected.
+ *
+ * Hopefully we will at least detect this condition
+ * when we try to grow the stack.
+ */
+ if ((prev_entry->next != &map->header) &&
+ (prev_entry->next->start < addrbos + max_ssize)) {
+ vm_map_unlock(map);
+ return (KERN_NO_SPACE);
+ }
+
+ /* We initially map a stack of only init_ssize. We will
+ * grow as needed later. Since this is to be a grow
+ * down stack, we map at the top of the range.
+ *
+ * Note: we would normally expect prot and max to be
+ * VM_PROT_ALL, and cow to be 0. Possibly we should
+ * eliminate these as input parameters, and just
+ * pass these values here in the insert call.
+ */
+ rv = vm_map_insert(map, NULL, 0, addrbos + max_ssize - init_ssize,
+ addrbos + max_ssize, prot, max, cow);
+
+ /* Now set the avail_ssize amount */
+ if (rv == KERN_SUCCESS){
+ new_stack_entry = prev_entry->next;
+ if (new_stack_entry->end != addrbos + max_ssize ||
+ new_stack_entry->start != addrbos + max_ssize - init_ssize)
+ panic ("Bad entry start/end for new stack entry");
+ else
+ new_stack_entry->avail_ssize = max_ssize - init_ssize;
+ }
+
+ vm_map_unlock(map);
+ return (rv);
+}
+
+/* Attempts to grow a vm stack entry. Returns KERN_SUCCESS if the
+ * desired address is already mapped, or if we successfully grow
+ * the stack. Also returns KERN_SUCCESS if addr is outside the
+ * stack range (this is strange, but preserves compatibility with
+ * the grow function in vm_machdep.c).
+ */
+int
+vm_map_growstack (struct proc *p, vm_offset_t addr)
+{
+ vm_map_entry_t prev_entry;
+ vm_map_entry_t stack_entry;
+ vm_map_entry_t new_stack_entry;
+ struct vmspace *vm = p->p_vmspace;
+ vm_map_t map = &vm->vm_map;
+ vm_offset_t end;
+ int grow_amount;
+ int rv;
+ int is_procstack;
+Retry:
+ vm_map_lock_read(map);
+
+ /* If addr is already in the entry range, no need to grow.*/
+ if (vm_map_lookup_entry(map, addr, &prev_entry)) {
+ vm_map_unlock_read(map);
+ return (KERN_SUCCESS);
+ }
+
+ if ((stack_entry = prev_entry->next) == &map->header) {
+ vm_map_unlock_read(map);
+ return (KERN_SUCCESS);
+ }
+ if (prev_entry == &map->header)
+ end = stack_entry->start - stack_entry->avail_ssize;
+ else
+ end = prev_entry->end;
+
+ /* This next test mimics the old grow function in vm_machdep.c.
+ * It really doesn't quite make sense, but we do it anyway
+ * for compatibility.
+ *
+ * If not growable stack, return success. This signals the
+ * caller to proceed as he would normally with normal vm.
+ */
+ if (stack_entry->avail_ssize < 1 ||
+ addr >= stack_entry->start ||
+ addr < stack_entry->start - stack_entry->avail_ssize) {
+ vm_map_unlock_read(map);
+ return (KERN_SUCCESS);
+ }
+
+ /* Find the minimum grow amount */
+ grow_amount = roundup (stack_entry->start - addr, PAGE_SIZE);
+ if (grow_amount > stack_entry->avail_ssize) {
+ vm_map_unlock_read(map);
+ return (KERN_NO_SPACE);
+ }
+
+ /* If there is no longer enough space between the entries
+ * nogo, and adjust the available space. Note: this
+ * should only happen if the user has mapped into the
+ * stack area after the stack was created, and is
+ * probably an error.
+ *
+ * This also effectively destroys any guard page the user
+ * might have intended by limiting the stack size.
+ */
+ if (grow_amount > stack_entry->start - end) {
+ if (vm_map_lock_upgrade(map))
+ goto Retry;
+
+ stack_entry->avail_ssize = stack_entry->start - end;
+
+ vm_map_unlock(map);
+ return (KERN_NO_SPACE);
+ }
+
+ is_procstack = addr >= (vm_offset_t)vm->vm_maxsaddr;
+
+ /* If this is the main process stack, see if we're over the
+ * stack limit.
+ */
+ if (is_procstack && (vm->vm_ssize + grow_amount >
+ p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
+ vm_map_unlock_read(map);
+ return (KERN_NO_SPACE);
+ }
+
+ /* Round up the grow amount modulo SGROWSIZ */
+ grow_amount = roundup (grow_amount, SGROWSIZ);
+ if (grow_amount > stack_entry->avail_ssize) {
+ grow_amount = stack_entry->avail_ssize;
+ }
+ if (is_procstack && (vm->vm_ssize + grow_amount >
+ p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
+ grow_amount = p->p_rlimit[RLIMIT_STACK].rlim_cur -
+ vm->vm_ssize;
+ }
+
+ if (vm_map_lock_upgrade(map))
+ goto Retry;
+
+ /* Get the preliminary new entry start value */
+ addr = stack_entry->start - grow_amount;
+
+ /* If this puts us into the previous entry, cut back our growth
+ * to the available space. Also, see the note above.
+ */
+ if (addr < end) {
+ stack_entry->avail_ssize = stack_entry->start - end;
+ addr = end;
+ }
+
+ rv = vm_map_insert(map, NULL, 0, addr, stack_entry->start,
+ stack_entry->protection,
+ stack_entry->max_protection,
+ 0);
+
+ /* Adjust the available stack space by the amount we grew. */
+ if (rv == KERN_SUCCESS) {
+ new_stack_entry = prev_entry->next;
+ if (new_stack_entry->end != stack_entry->start ||
+ new_stack_entry->start != addr)
+ panic ("Bad stack grow start/end in new stack entry");
+ else {
+ new_stack_entry->avail_ssize = stack_entry->avail_ssize -
+ (new_stack_entry->end -
+ new_stack_entry->start);
+ if (is_procstack)
+ vm->vm_ssize += new_stack_entry->end -
+ new_stack_entry->start;
+ }
+ }
+
+ vm_map_unlock(map);
+ return (rv);
+
+}
+
/*
* Unshare the specified VM space for exec. If other processes are
* mapped to it, then create a new one. The new vmspace is null.
OpenPOWER on IntegriCloud