summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/linux/linux_sysvec.c23
-rw-r--r--sys/amd64/amd64/machdep.c6
-rw-r--r--sys/amd64/amd64/trap.c38
-rw-r--r--sys/amd64/amd64/vm_machdep.c19
-rw-r--r--sys/compat/linux/linux_misc.c93
-rw-r--r--sys/i386/i386/machdep.c6
-rw-r--r--sys/i386/i386/trap.c38
-rw-r--r--sys/i386/i386/vm_machdep.c19
-rw-r--r--sys/i386/linux/linux_misc.c93
-rw-r--r--sys/i386/linux/linux_sysvec.c23
-rw-r--r--sys/kern/kern_exec.c20
-rw-r--r--sys/kern/subr_trap.c38
-rw-r--r--sys/sys/mman.h5
-rw-r--r--sys/vm/vm_extern.h6
-rw-r--r--sys/vm/vm_map.c207
-rw-r--r--sys/vm/vm_map.h9
-rw-r--r--sys/vm/vm_mmap.c17
17 files changed, 513 insertions, 147 deletions
diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c
index 611899c..da1d78f 100644
--- a/sys/alpha/linux/linux_sysvec.c
+++ b/sys/alpha/linux/linux_sysvec.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: linux_sysvec.c,v 1.41 1998/12/19 02:55:33 julian Exp $
+ * $Id: linux_sysvec.c,v 1.42 1998/12/19 19:05:57 sos Exp $
*/
/* XXX we use functions that might not exist. */
@@ -50,10 +50,6 @@
#include <vm/vm_prot.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
-#ifdef COMPAT_LINUX_THREADS
-#include <sys/lock.h> /* needed, for now, by vm_map.h */
-#include <vm/vm_map.h> /* needed, for now, for VM_STACK defines */
-#endif /* COMPAT_LINUX_THREADS */
#include <sys/exec.h>
#include <sys/kernel.h>
#include <sys/module.h>
@@ -221,24 +217,11 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code)
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
-#ifdef COMPAT_LINUX_THREADS
-#ifdef USE_VM_STACK
-#ifndef USE_VM_STACK_FOR_EXEC
- if ((((caddr_t)fp > p->p_vmspace->vm_maxsaddr &&
- (caddr_t)fp < (caddr_t)USRSTACK &&
- grow(p, (int)fp) == FALSE) ||
- (((caddr_t)fp <= p->p_vmspace->vm_maxsaddr ||
- (caddr_t)fp >= (caddr_t)USRSTACK) &&
- grow_stack (p, (int)fp) == FALSE)) ||
-#else
+#ifdef VM_STACK
if ((grow_stack (p, (int)fp) == FALSE) ||
-#endif /* USE_VM_STACK_FOR_EXEC */
-#else
- if ((grow(p, (int)fp) == FALSE) ||
-#endif /* USE_VM_STACK */
#else
if ((grow(p, (int)fp) == FALSE) ||
-#endif /* COMPAT_LINUX_THREADS */
+#endif
(useracc((caddr_t)fp, sizeof (struct linux_sigframe), B_WRITE) == FALSE)) {
/*
* Process has trashed its stack; give it an illegal
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 45c5e8f..cb4f514 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.318 1998/12/10 01:49:01 steve Exp $
+ * $Id: machdep.c,v 1.319 1998/12/16 16:28:56 bde Exp $
*/
#include "apm.h"
@@ -525,7 +525,11 @@ sendsig(catcher, sig, mask, code)
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
+#ifdef VM_STACK
+ if ((grow_stack (p, (int)fp) == FALSE) ||
+#else
if ((grow(p, (int)fp) == FALSE) ||
+#endif
(useracc((caddr_t)fp, sizeof(struct sigframe), B_WRITE) == FALSE)) {
/*
* Process has trashed its stack; give it an illegal
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index e672368..42b0c85 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.131 1998/12/16 15:21:50 bde Exp $
+ * $Id: trap.c,v 1.132 1998/12/28 23:02:56 msmith Exp $
*/
/*
@@ -665,6 +665,7 @@ trap_pfault(frame, usermode, eva)
/*
* Grow the stack if necessary
*/
+#ifndef VM_STACK
if ((caddr_t)va > vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
rv = KERN_FAILURE;
@@ -673,6 +674,20 @@ trap_pfault(frame, usermode, eva)
}
}
+#else
+ /* grow_stack returns false only if va falls into
+ * a growable stack region and the stack growth
+ * fails. It returns true if va was not within
+ * a growable stack region, or if the stack
+ * growth succeeded.
+ */
+ if (!grow_stack (p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+#endif
+
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : 0);
@@ -775,6 +790,7 @@ trap_pfault(frame, usermode, eva)
/*
* Grow the stack if necessary
*/
+#ifndef VM_STACK
if ((caddr_t)va > vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
rv = KERN_FAILURE;
@@ -782,6 +798,19 @@ trap_pfault(frame, usermode, eva)
goto nogo;
}
}
+#else
+ /* grow_stack returns false only if va falls into
+ * a growable stack region and the stack growth
+ * fails. It returns true if va was not within
+ * a growable stack region, or if the stack
+ * growth succeeded.
+ */
+ if (!grow_stack (p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+#endif
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
@@ -969,12 +998,19 @@ int trapwrite(addr)
++p->p_lock;
+#ifndef VM_STACK
if ((caddr_t)va >= vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
--p->p_lock;
return (1);
}
}
+#else
+ if (!grow_stack (p, va)) {
+ --p->p_lock;
+ return (1);
+ }
+#endif
/*
* fault the data page
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 761008e..d0bdc93 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.113 1998/10/31 17:21:30 peter Exp $
+ * $Id: vm_machdep.c,v 1.114 1998/12/16 15:21:51 bde Exp $
*/
#include "npx.h"
@@ -507,6 +507,7 @@ cpu_reset_real()
while(1);
}
+#ifndef VM_STACK
/*
* Grow the user stack to allow for 'sp'. This version grows the stack in
* chunks of SGROWSIZ.
@@ -559,6 +560,22 @@ grow(p, sp)
return (1);
}
+#else
+int
+grow_stack(p, sp)
+ struct proc *p;
+ u_int sp;
+{
+ int rv;
+
+ rv = vm_map_growstack (p, sp);
+ if (rv != KERN_SUCCESS)
+ return (0);
+
+ return (1);
+}
+#endif
+
static int cnt_prezero;
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 3bdc805..02f9785 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: linux_misc.c,v 1.49 1998/12/24 21:21:20 julian Exp $
+ * $Id: linux_misc.c,v 1.50 1998/12/30 21:01:33 sos Exp $
*/
#include <sys/param.h>
@@ -688,45 +688,44 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args)
bsd_args.len = linux_args.len;
#else
- /*#if !defined(USE_VM_STACK) && !defined(USE_VM_STACK_FOR_EXEC)*/
+#ifndef VM_STACK
/* Linux Threads will map into the proc stack space, unless
- we prevent it. This causes problems if we're not using
- our VM_STACK options.
- */
+ * we prevent it. This causes problems if we're not using
+ * our VM_STACK options.
+ */
if ((unsigned int)linux_args.addr + linux_args.len > (USRSTACK - MAXSSIZ))
- return (EINVAL);
- /*#endif*/
+ return (EINVAL);
+#endif
if (linux_args.flags & LINUX_MAP_GROWSDOWN) {
-#ifdef USE_VM_STACK
- /* USE_VM_STACK is defined (or not) in vm/vm_map.h */
- bsd_args.flags |= MAP_STACK;
+#ifdef VM_STACK
+ bsd_args.flags |= MAP_STACK;
#endif
/* The linux MAP_GROWSDOWN option does not limit auto
- growth of the region. Linux mmap with this option
- takes as addr the inital BOS, and as len, the initial
- region size. It can then grow down from addr without
- limit. However, linux threads has an implicit internal
- limit to stack size of STACK_SIZE. Its just not
- enforced explicitly in linux. But, here we impose
- a limit of (STACK_SIZE - GUARD_SIZE) on the stack
- region, since we can do this with our mmap.
-
- Our mmap with MAP_STACK takes addr as the maximum
- downsize limit on BOS, and as len the max size of
- the region. It them maps the top SGROWSIZ bytes,
- and autgrows the region down, up to the limit
- in addr.
-
- If we don't use the MAP_STACK option, the effect
- of this code is to allocate a stack region of a
- fixed size of (STACK_SIZE - GUARD_SIZE).
- */
+ * growth of the region. Linux mmap with this option
+ * takes as addr the inital BOS, and as len, the initial
+ * region size. It can then grow down from addr without
+ * limit. However, linux threads has an implicit internal
+ * limit to stack size of STACK_SIZE. Its just not
+ * enforced explicitly in linux. But, here we impose
+ * a limit of (STACK_SIZE - GUARD_SIZE) on the stack
+ * region, since we can do this with our mmap.
+ *
+ * Our mmap with MAP_STACK takes addr as the maximum
+ * downsize limit on BOS, and as len the max size of
+ * the region. It them maps the top SGROWSIZ bytes,
+ * and autgrows the region down, up to the limit
+ * in addr.
+ *
+ * If we don't use the MAP_STACK option, the effect
+ * of this code is to allocate a stack region of a
+ * fixed size of (STACK_SIZE - GUARD_SIZE).
+ */
/* This gives us TOS */
- bsd_args.addr = linux_args.addr + linux_args.len;
+ bsd_args.addr = linux_args.addr + linux_args.len;
/* This gives us our maximum stack size */
if (linux_args.len > STACK_SIZE - GUARD_SIZE)
@@ -735,15 +734,15 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args)
bsd_args.len = STACK_SIZE - GUARD_SIZE;
/* This gives us a new BOS. If we're using VM_STACK, then
- mmap will just map the top SGROWSIZ bytes, and let
- the stack grow down to the limit at BOS. If we're
- not using VM_STACK we map the full stack, since we
- don't have a way to autogrow it.
- */
+ * mmap will just map the top SGROWSIZ bytes, and let
+ * the stack grow down to the limit at BOS. If we're
+ * not using VM_STACK we map the full stack, since we
+ * don't have a way to autogrow it.
+ */
bsd_args.addr -= bsd_args.len;
} else {
- bsd_args.addr = linux_args.addr;
+ bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
}
#endif /* COMPAT_LINUX_THREADS */
@@ -977,11 +976,11 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
- think we need it, but I could be wrong. If we need
- it, we need to fix wait4, since it will give us an
- error return of EINVAL if we pass in _WCLONE, and
- of course, it won't do anything with it.
- */
+ * think we need it, but I could be wrong. If we need
+ * it, we need to fix wait4, since it will give us an
+ * error return of EINVAL if we pass in _WCLONE, and
+ * of course, it won't do anything with it.
+ */
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = NULL;
@@ -990,7 +989,7 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
#ifndef COMPAT_LINUX_THREADS
return error;
#else
- return error;
+ return error;
#endif /* COMPAT_LINUX_THREADS */
if (args->status) {
if (error = copyin(args->status, &tmpstat, sizeof(int)))
@@ -1028,11 +1027,11 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args)
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
- think we need it, but I could be wrong. If we need
- it, we need to fix wait4, since it will give us an
- error return of EINVAL if we pass in _WCLONE, and
- of course, it won't do anything with it.
- */
+ * think we need it, but I could be wrong. If we need
+ * it, we need to fix wait4, since it will give us an
+ * error return of EINVAL if we pass in _WCLONE, and
+ * of course, it won't do anything with it.
+ */
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = args->rusage;
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 45c5e8f..cb4f514 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.318 1998/12/10 01:49:01 steve Exp $
+ * $Id: machdep.c,v 1.319 1998/12/16 16:28:56 bde Exp $
*/
#include "apm.h"
@@ -525,7 +525,11 @@ sendsig(catcher, sig, mask, code)
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
+#ifdef VM_STACK
+ if ((grow_stack (p, (int)fp) == FALSE) ||
+#else
if ((grow(p, (int)fp) == FALSE) ||
+#endif
(useracc((caddr_t)fp, sizeof(struct sigframe), B_WRITE) == FALSE)) {
/*
* Process has trashed its stack; give it an illegal
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index e672368..42b0c85 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.131 1998/12/16 15:21:50 bde Exp $
+ * $Id: trap.c,v 1.132 1998/12/28 23:02:56 msmith Exp $
*/
/*
@@ -665,6 +665,7 @@ trap_pfault(frame, usermode, eva)
/*
* Grow the stack if necessary
*/
+#ifndef VM_STACK
if ((caddr_t)va > vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
rv = KERN_FAILURE;
@@ -673,6 +674,20 @@ trap_pfault(frame, usermode, eva)
}
}
+#else
+ /* grow_stack returns false only if va falls into
+ * a growable stack region and the stack growth
+ * fails. It returns true if va was not within
+ * a growable stack region, or if the stack
+ * growth succeeded.
+ */
+ if (!grow_stack (p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+#endif
+
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : 0);
@@ -775,6 +790,7 @@ trap_pfault(frame, usermode, eva)
/*
* Grow the stack if necessary
*/
+#ifndef VM_STACK
if ((caddr_t)va > vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
rv = KERN_FAILURE;
@@ -782,6 +798,19 @@ trap_pfault(frame, usermode, eva)
goto nogo;
}
}
+#else
+ /* grow_stack returns false only if va falls into
+ * a growable stack region and the stack growth
+ * fails. It returns true if va was not within
+ * a growable stack region, or if the stack
+ * growth succeeded.
+ */
+ if (!grow_stack (p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+#endif
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
@@ -969,12 +998,19 @@ int trapwrite(addr)
++p->p_lock;
+#ifndef VM_STACK
if ((caddr_t)va >= vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
--p->p_lock;
return (1);
}
}
+#else
+ if (!grow_stack (p, va)) {
+ --p->p_lock;
+ return (1);
+ }
+#endif
/*
* fault the data page
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 761008e..d0bdc93 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.113 1998/10/31 17:21:30 peter Exp $
+ * $Id: vm_machdep.c,v 1.114 1998/12/16 15:21:51 bde Exp $
*/
#include "npx.h"
@@ -507,6 +507,7 @@ cpu_reset_real()
while(1);
}
+#ifndef VM_STACK
/*
* Grow the user stack to allow for 'sp'. This version grows the stack in
* chunks of SGROWSIZ.
@@ -559,6 +560,22 @@ grow(p, sp)
return (1);
}
+#else
+int
+grow_stack(p, sp)
+ struct proc *p;
+ u_int sp;
+{
+ int rv;
+
+ rv = vm_map_growstack (p, sp);
+ if (rv != KERN_SUCCESS)
+ return (0);
+
+ return (1);
+}
+#endif
+
static int cnt_prezero;
diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c
index 3bdc805..02f9785 100644
--- a/sys/i386/linux/linux_misc.c
+++ b/sys/i386/linux/linux_misc.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: linux_misc.c,v 1.49 1998/12/24 21:21:20 julian Exp $
+ * $Id: linux_misc.c,v 1.50 1998/12/30 21:01:33 sos Exp $
*/
#include <sys/param.h>
@@ -688,45 +688,44 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args)
bsd_args.len = linux_args.len;
#else
- /*#if !defined(USE_VM_STACK) && !defined(USE_VM_STACK_FOR_EXEC)*/
+#ifndef VM_STACK
/* Linux Threads will map into the proc stack space, unless
- we prevent it. This causes problems if we're not using
- our VM_STACK options.
- */
+ * we prevent it. This causes problems if we're not using
+ * our VM_STACK options.
+ */
if ((unsigned int)linux_args.addr + linux_args.len > (USRSTACK - MAXSSIZ))
- return (EINVAL);
- /*#endif*/
+ return (EINVAL);
+#endif
if (linux_args.flags & LINUX_MAP_GROWSDOWN) {
-#ifdef USE_VM_STACK
- /* USE_VM_STACK is defined (or not) in vm/vm_map.h */
- bsd_args.flags |= MAP_STACK;
+#ifdef VM_STACK
+ bsd_args.flags |= MAP_STACK;
#endif
/* The linux MAP_GROWSDOWN option does not limit auto
- growth of the region. Linux mmap with this option
- takes as addr the inital BOS, and as len, the initial
- region size. It can then grow down from addr without
- limit. However, linux threads has an implicit internal
- limit to stack size of STACK_SIZE. Its just not
- enforced explicitly in linux. But, here we impose
- a limit of (STACK_SIZE - GUARD_SIZE) on the stack
- region, since we can do this with our mmap.
-
- Our mmap with MAP_STACK takes addr as the maximum
- downsize limit on BOS, and as len the max size of
- the region. It them maps the top SGROWSIZ bytes,
- and autgrows the region down, up to the limit
- in addr.
-
- If we don't use the MAP_STACK option, the effect
- of this code is to allocate a stack region of a
- fixed size of (STACK_SIZE - GUARD_SIZE).
- */
+ * growth of the region. Linux mmap with this option
+ * takes as addr the inital BOS, and as len, the initial
+ * region size. It can then grow down from addr without
+ * limit. However, linux threads has an implicit internal
+ * limit to stack size of STACK_SIZE. Its just not
+ * enforced explicitly in linux. But, here we impose
+ * a limit of (STACK_SIZE - GUARD_SIZE) on the stack
+ * region, since we can do this with our mmap.
+ *
+ * Our mmap with MAP_STACK takes addr as the maximum
+ * downsize limit on BOS, and as len the max size of
+ * the region. It them maps the top SGROWSIZ bytes,
+ * and autgrows the region down, up to the limit
+ * in addr.
+ *
+ * If we don't use the MAP_STACK option, the effect
+ * of this code is to allocate a stack region of a
+ * fixed size of (STACK_SIZE - GUARD_SIZE).
+ */
/* This gives us TOS */
- bsd_args.addr = linux_args.addr + linux_args.len;
+ bsd_args.addr = linux_args.addr + linux_args.len;
/* This gives us our maximum stack size */
if (linux_args.len > STACK_SIZE - GUARD_SIZE)
@@ -735,15 +734,15 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args)
bsd_args.len = STACK_SIZE - GUARD_SIZE;
/* This gives us a new BOS. If we're using VM_STACK, then
- mmap will just map the top SGROWSIZ bytes, and let
- the stack grow down to the limit at BOS. If we're
- not using VM_STACK we map the full stack, since we
- don't have a way to autogrow it.
- */
+ * mmap will just map the top SGROWSIZ bytes, and let
+ * the stack grow down to the limit at BOS. If we're
+ * not using VM_STACK we map the full stack, since we
+ * don't have a way to autogrow it.
+ */
bsd_args.addr -= bsd_args.len;
} else {
- bsd_args.addr = linux_args.addr;
+ bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
}
#endif /* COMPAT_LINUX_THREADS */
@@ -977,11 +976,11 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
- think we need it, but I could be wrong. If we need
- it, we need to fix wait4, since it will give us an
- error return of EINVAL if we pass in _WCLONE, and
- of course, it won't do anything with it.
- */
+ * think we need it, but I could be wrong. If we need
+ * it, we need to fix wait4, since it will give us an
+ * error return of EINVAL if we pass in _WCLONE, and
+ * of course, it won't do anything with it.
+ */
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = NULL;
@@ -990,7 +989,7 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
#ifndef COMPAT_LINUX_THREADS
return error;
#else
- return error;
+ return error;
#endif /* COMPAT_LINUX_THREADS */
if (args->status) {
if (error = copyin(args->status, &tmpstat, sizeof(int)))
@@ -1028,11 +1027,11 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args)
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
- think we need it, but I could be wrong. If we need
- it, we need to fix wait4, since it will give us an
- error return of EINVAL if we pass in _WCLONE, and
- of course, it won't do anything with it.
- */
+ * think we need it, but I could be wrong. If we need
+ * it, we need to fix wait4, since it will give us an
+ * error return of EINVAL if we pass in _WCLONE, and
+ * of course, it won't do anything with it.
+ */
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = args->rusage;
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 611899c..da1d78f 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: linux_sysvec.c,v 1.41 1998/12/19 02:55:33 julian Exp $
+ * $Id: linux_sysvec.c,v 1.42 1998/12/19 19:05:57 sos Exp $
*/
/* XXX we use functions that might not exist. */
@@ -50,10 +50,6 @@
#include <vm/vm_prot.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
-#ifdef COMPAT_LINUX_THREADS
-#include <sys/lock.h> /* needed, for now, by vm_map.h */
-#include <vm/vm_map.h> /* needed, for now, for VM_STACK defines */
-#endif /* COMPAT_LINUX_THREADS */
#include <sys/exec.h>
#include <sys/kernel.h>
#include <sys/module.h>
@@ -221,24 +217,11 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code)
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
-#ifdef COMPAT_LINUX_THREADS
-#ifdef USE_VM_STACK
-#ifndef USE_VM_STACK_FOR_EXEC
- if ((((caddr_t)fp > p->p_vmspace->vm_maxsaddr &&
- (caddr_t)fp < (caddr_t)USRSTACK &&
- grow(p, (int)fp) == FALSE) ||
- (((caddr_t)fp <= p->p_vmspace->vm_maxsaddr ||
- (caddr_t)fp >= (caddr_t)USRSTACK) &&
- grow_stack (p, (int)fp) == FALSE)) ||
-#else
+#ifdef VM_STACK
if ((grow_stack (p, (int)fp) == FALSE) ||
-#endif /* USE_VM_STACK_FOR_EXEC */
-#else
- if ((grow(p, (int)fp) == FALSE) ||
-#endif /* USE_VM_STACK */
#else
if ((grow(p, (int)fp) == FALSE) ||
-#endif /* COMPAT_LINUX_THREADS */
+#endif
(useracc((caddr_t)fp, sizeof (struct linux_sigframe), B_WRITE) == FALSE)) {
/*
* Process has trashed its stack; give it an illegal
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index fc23c6e..dd63672 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: kern_exec.c,v 1.91 1998/12/27 18:03:29 dfr Exp $
+ * $Id: kern_exec.c,v 1.92 1998/12/30 10:38:59 dfr Exp $
*/
#include <sys/param.h>
@@ -426,7 +426,11 @@ exec_new_vmspace(imgp)
{
int error;
struct vmspace *vmspace = imgp->proc->p_vmspace;
+#ifdef VM_STACK
+ caddr_t stack_addr = (caddr_t) (USRSTACK - MAXSSIZ);
+#else
caddr_t stack_addr = (caddr_t) (USRSTACK - SGROWSIZ);
+#endif
vm_map_t map = &vmspace->vm_map;
imgp->vmspace_destroyed = 1;
@@ -448,6 +452,19 @@ exec_new_vmspace(imgp)
}
/* Allocate a new stack */
+#ifdef VM_STACK
+ error = vm_map_stack (&vmspace->vm_map, (vm_offset_t)stack_addr,
+ (vm_size_t)MAXSSIZ, VM_PROT_ALL, VM_PROT_ALL, 0);
+ if (error)
+ return (error);
+
+ /* vm_ssize and vm_maxsaddr are somewhat antiquated concepts in the
+ * VM_STACK case, but they are still used to monitor the size of the
+ * process stack so we can check the stack rlimit.
+ */
+ vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT;
+ vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ;
+#else
error = vm_map_insert(&vmspace->vm_map, NULL, 0,
(vm_offset_t) stack_addr, (vm_offset_t) USRSTACK,
VM_PROT_ALL, VM_PROT_ALL, 0);
@@ -458,6 +475,7 @@ exec_new_vmspace(imgp)
/* Initialize maximum stack address */
vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ;
+#endif
return(0);
}
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index e672368..42b0c85 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.131 1998/12/16 15:21:50 bde Exp $
+ * $Id: trap.c,v 1.132 1998/12/28 23:02:56 msmith Exp $
*/
/*
@@ -665,6 +665,7 @@ trap_pfault(frame, usermode, eva)
/*
* Grow the stack if necessary
*/
+#ifndef VM_STACK
if ((caddr_t)va > vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
rv = KERN_FAILURE;
@@ -673,6 +674,20 @@ trap_pfault(frame, usermode, eva)
}
}
+#else
+ /* grow_stack returns false only if va falls into
+ * a growable stack region and the stack growth
+ * fails. It returns true if va was not within
+ * a growable stack region, or if the stack
+ * growth succeeded.
+ */
+ if (!grow_stack (p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+#endif
+
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : 0);
@@ -775,6 +790,7 @@ trap_pfault(frame, usermode, eva)
/*
* Grow the stack if necessary
*/
+#ifndef VM_STACK
if ((caddr_t)va > vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
rv = KERN_FAILURE;
@@ -782,6 +798,19 @@ trap_pfault(frame, usermode, eva)
goto nogo;
}
}
+#else
+ /* grow_stack returns false only if va falls into
+ * a growable stack region and the stack growth
+ * fails. It returns true if va was not within
+ * a growable stack region, or if the stack
+ * growth succeeded.
+ */
+ if (!grow_stack (p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+#endif
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
@@ -969,12 +998,19 @@ int trapwrite(addr)
++p->p_lock;
+#ifndef VM_STACK
if ((caddr_t)va >= vm->vm_maxsaddr && va < USRSTACK) {
if (!grow(p, va)) {
--p->p_lock;
return (1);
}
}
+#else
+ if (!grow_stack (p, va)) {
+ --p->p_lock;
+ return (1);
+ }
+#endif
/*
* fault the data page
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
index 1ef5669..c659243 100644
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mman.h 8.2 (Berkeley) 1/9/95
- * $Id: mman.h,v 1.22 1998/03/08 17:25:33 dufault Exp $
+ * $Id: mman.h,v 1.23 1998/03/28 11:50:38 dufault Exp $
*/
#ifndef _SYS_MMAN_H_
@@ -64,6 +64,9 @@
#define MAP_INHERIT 0x0080 /* region is retained after exec */
#define MAP_NOEXTEND 0x0100 /* for MAP_FILE, don't change file size */
#define MAP_HASSEMAPHORE 0x0200 /* region may contain semaphores */
+#ifdef VM_STACK
+#define MAP_STACK 0x0400 /* region grows down, like a stack */
+#endif
#ifdef _P1003_1B_VISIBLE
/*
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
index 34deba7..ca5a53e 100644
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_extern.h 8.2 (Berkeley) 1/12/94
- * $Id: vm_extern.h,v 1.37 1998/01/22 17:30:32 dyson Exp $
+ * $Id: vm_extern.h,v 1.38 1998/06/07 17:13:09 dfr Exp $
*/
#ifndef _VM_EXTERN_H_
@@ -61,7 +61,11 @@ int swapon __P((struct proc *, void *, int *));
#endif
void faultin __P((struct proc *p));
+#ifndef VM_STACK
int grow __P((struct proc *, size_t));
+#else
+int grow_stack __P((struct proc *, size_t));
+#endif
int kernacc __P((caddr_t, int, int));
vm_offset_t kmem_alloc __P((vm_map_t, vm_size_t));
vm_offset_t kmem_alloc_pageable __P((vm_map_t, vm_size_t));
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 83132ad..829548a 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.137 1998/10/13 08:24:43 dg Exp $
+ * $Id: vm_map.c,v 1.138 1998/10/25 17:44:58 phk Exp $
*/
/*
@@ -75,6 +75,9 @@
#include <sys/vmmeter.h>
#include <sys/mman.h>
#include <sys/vnode.h>
+#ifdef VM_STACK
+#include <sys/resourcevar.h>
+#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -538,6 +541,10 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
new_entry->eflags = protoeflags;
new_entry->object.vm_object = object;
new_entry->offset = offset;
+#ifdef VM_STACK
+ new_entry->avail_ssize = 0;
+#endif
+
if (object) {
if ((object->ref_count > 1) || (object->shadow_count != 0)) {
vm_object_clear_flag(object, OBJ_ONEMAPPING);
@@ -570,6 +577,204 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
return (KERN_SUCCESS);
}
+#ifdef VM_STACK
+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 = 0;
+
+ vm_map_lock(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(map);
+ return (KERN_SUCCESS);
+ }
+
+ if ((stack_entry = prev_entry->next) == &map->header) {
+ vm_map_unlock(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(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(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) {
+ stack_entry->avail_ssize = stack_entry->start - end;
+ vm_map_unlock(map);
+ return (KERN_NO_SPACE);
+ }
+
+ if (addr >= (vm_offset_t)vm->vm_maxsaddr)
+ is_procstack = 1;
+
+ /* 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(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;
+ }
+
+ /* 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);
+ vm->vm_ssize += new_stack_entry->end -
+ new_stack_entry->start;
+ }
+ }
+
+ vm_map_unlock(map);
+ return (rv);
+
+}
+#endif
+
/*
* 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.
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index b7c6cd5..4d61a3f 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.h,v 1.31 1998/01/17 09:16:52 dyson Exp $
+ * $Id: vm_map.h,v 1.32 1998/01/22 17:30:38 dyson Exp $
*/
/*
@@ -102,6 +102,9 @@ struct vm_map_entry {
struct vm_map_entry *next; /* next entry */
vm_offset_t start; /* start address */
vm_offset_t end; /* end address */
+#ifdef VM_STACK
+ vm_offset_t avail_ssize; /* amt can grow if this is a stack */
+#endif
union vm_map_object object; /* object I point to */
vm_ooffset_t offset; /* offset into object */
u_char eflags; /* map entry flags */
@@ -335,6 +338,10 @@ void vm_map_simplify_entry __P((vm_map_t, vm_map_entry_t));
void vm_init2 __P((void));
int vm_uiomove __P((vm_map_t, vm_object_t, off_t, int, vm_offset_t, int *));
void vm_freeze_copyopts __P((vm_object_t, vm_pindex_t, vm_pindex_t));
+#ifdef VM_STACK
+int vm_map_stack __P((vm_map_t, vm_offset_t, vm_size_t, vm_prot_t, vm_prot_t, int));
+int vm_map_growstack __P((struct proc *p, vm_offset_t addr));
+#endif
#endif
#endif /* _VM_MAP_ */
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 180ad25..ba36e41 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
- * $Id: vm_mmap.c,v 1.84 1998/10/13 08:24:44 dg Exp $
+ * $Id: vm_mmap.c,v 1.85 1998/12/09 20:22:21 dt Exp $
*/
/*
@@ -177,6 +177,15 @@ mmap(p, uap)
((flags & MAP_ANON) && uap->fd != -1))
return (EINVAL);
+#ifdef VM_STACK
+ if (flags & MAP_STACK) {
+ if ((uap->fd != -1) ||
+ ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)))
+ return (EINVAL);
+ flags |= MAP_ANON;
+ pos = 0;
+ }
+#endif
/*
* Align the file position to a page boundary,
* and save its page offset component.
@@ -1016,6 +1025,12 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
*addr = pmap_addr_hint(object, *addr, size);
}
+#ifdef VM_STACK
+ if (flags & MAP_STACK)
+ rv = vm_map_stack (map, *addr, size, prot,
+ maxprot, docow);
+ else
+#endif
rv = vm_map_find(map, object, foff, addr, size, fitit,
prot, maxprot, docow);
OpenPOWER on IntegriCloud