This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.1'.
[unix-history] / sys / i386 / i386 / vm_machdep.c
index 57f2ee3..f99861a 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     from: @(#)vm_machdep.c  7.3 (Berkeley) 5/13/91
  *     Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
  *
  *     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.8 1993/12/19 00:50:10 wollman Exp $
+ *     $Id: vm_machdep.c,v 1.11 1994/02/08 09:26:04 davidg Exp $
  */
 
 #include "npx.h"
  */
 
 #include "npx.h"
@@ -252,98 +252,6 @@ kvtop(void *addr)
        return((int)va);
 }
 
        return((int)va);
 }
 
-#ifdef notdef
-/*
- * The probe[rw] routines should probably be redone in assembler
- * for efficiency.
- */
-prober(addr)
-       register u_int addr;
-{
-       register int page;
-       register struct proc *p;
-
-       if (addr >= USRSTACK)
-               return(0);
-       p = u.u_procp;
-       page = btop(addr);
-       if (page < dptov(p, p->p_dsize) || page > sptov(p, p->p_ssize))
-               return(1);
-       return(0);
-}
-
-probew(addr)
-       register u_int addr;
-{
-       register int page;
-       register struct proc *p;
-
-       if (addr >= USRSTACK)
-               return(0);
-       p = u.u_procp;
-       page = btop(addr);
-       if (page < dptov(p, p->p_dsize) || page > sptov(p, p->p_ssize))
-               return((*(int *)vtopte(p, page) & PG_PROT) == PG_UW);
-       return(0);
-}
-
-/*
- * NB: assumes a physically contiguous kernel page table
- *     (makes life a LOT simpler).
- */
-int
-kernacc(addr, count, rw)
-       register u_int addr;
-       int count, rw;
-{
-       register struct pde *pde;
-       register struct pte *pte;
-       register int ix, cnt;
-       extern long Syssize;
-
-       if (count <= 0)
-               return(0);
-       pde = (struct pde *)((u_int)u.u_procp->p_p0br + u.u_procp->p_szpt * NBPG);
-       ix = (addr & PD_MASK) >> PD_SHIFT;
-       cnt = ((addr + count + (1 << PD_SHIFT) - 1) & PD_MASK) >> PD_SHIFT;
-       cnt -= ix;
-       for (pde += ix; cnt; cnt--, pde++)
-               if (pde->pd_v == 0)
-                       return(0);
-       ix = btop(addr-KERNBASE);
-       cnt = btop(addr-KERNBASE+count+NBPG-1);
-       if (cnt > (int)&Syssize)
-               return(0);
-       cnt -= ix;
-       for (pte = &Sysmap[ix]; cnt; cnt--, pte++)
-               if (pte->pg_v == 0 /*|| (rw == B_WRITE && pte->pg_prot == 1)*/) 
-                       return(0);
-       return(1);
-}
-
-int
-useracc(addr, count, rw)
-       register u_int addr;
-       int count, rw;
-{
-       register int (*func)();
-       register u_int addr2;
-       extern int prober(), probew();
-
-       if (count <= 0)
-               return(0);
-       addr2 = addr;
-       addr += count;
-       func = (rw == B_READ) ? prober : probew;
-       do {
-               if ((*func)(addr2) == 0)
-                       return(0);
-               addr2 = (addr2 + NBPG) & ~PGOFSET;
-       } while (addr2 < addr);
-       return(1);
-}
-#endif
-
 extern vm_map_t phys_map;
 
 /*
 extern vm_map_t phys_map;
 
 /*
@@ -430,3 +338,56 @@ cpu_reset() {
        /* NOTREACHED */
        while(1);
 }
        /* NOTREACHED */
        while(1);
 }
+
+/*
+ * Grow the user stack to allow for 'sp'. This version grows the stack in
+ *     chunks of SGROWSIZ.
+ */
+int
+grow(p, sp)
+       struct proc *p;
+       int sp;
+{
+       unsigned int nss;
+       caddr_t v;
+       struct vmspace *vm = p->p_vmspace;
+
+       if ((caddr_t)sp <= vm->vm_maxsaddr || (unsigned)sp >= (unsigned)USRSTACK)
+           return (1);
+
+       nss = roundup(USRSTACK - (unsigned)sp, PAGE_SIZE);
+
+       if (nss > p->p_rlimit[RLIMIT_STACK].rlim_cur)
+               return (0);
+
+       if (vm->vm_ssize && roundup(vm->vm_ssize << PAGE_SHIFT,
+           SGROWSIZ) < nss) {
+               int grow_amount;
+               /*
+                * If necessary, grow the VM that the stack occupies
+                * to allow for the rlimit. This allows us to not have
+                * to allocate all of the VM up-front in execve (which
+                * is expensive).
+                * Grow the VM by the amount requested rounded up to
+                * the nearest SGROWSIZ to provide for some hysteresis.
+                */
+               grow_amount = roundup((nss - (vm->vm_ssize << PAGE_SHIFT)), SGROWSIZ);
+               v = (char *)USRSTACK - roundup(vm->vm_ssize << PAGE_SHIFT,
+                   SGROWSIZ) - grow_amount;
+               /*
+                * If there isn't enough room to extend by SGROWSIZ, then
+                * just extend to the maximum size
+                */
+               if (v < vm->vm_maxsaddr) {
+                       v = vm->vm_maxsaddr;
+                       grow_amount = MAXSSIZ - (vm->vm_ssize << PAGE_SHIFT);
+               }
+               if (vm_allocate(&vm->vm_map, (vm_offset_t *)&v,
+                   grow_amount, FALSE) != KERN_SUCCESS) {
+                       return (0);
+               }
+               vm->vm_ssize += grow_amount >> PAGE_SHIFT;
+       }
+
+       return (1);
+}