145749Smckusick /*
245749Smckusick * Copyright (c) 1988 University of Utah.
363379Sbostic * Copyright (c) 1991, 1993
463379Sbostic * The Regents of the University of California. All rights reserved.
545749Smckusick *
645749Smckusick * This code is derived from software contributed to Berkeley by
745749Smckusick * the Systems Programming Group of the University of Utah Computer
845749Smckusick * Science Department.
945749Smckusick *
1045749Smckusick * %sccs.include.redist.c%
1145749Smckusick *
1245749Smckusick * from: Utah $Hdr: vm_unix.c 1.1 89/11/07$
1345749Smckusick *
14*68164Scgd * @(#)vm_unix.c 8.2 (Berkeley) 01/09/95
1545749Smckusick */
1645749Smckusick
1745749Smckusick /*
1845749Smckusick * Traditional sbrk/grow interface to VM
1945749Smckusick */
2053358Sbostic #include <sys/param.h>
2153358Sbostic #include <sys/systm.h>
2253358Sbostic #include <sys/proc.h>
2353358Sbostic #include <sys/resourcevar.h>
2445749Smckusick
2553358Sbostic #include <vm/vm.h>
2645749Smckusick
2754915Storek struct obreak_args {
2854915Storek char *nsiz;
2954915Storek };
3045749Smckusick /* ARGSUSED */
3153358Sbostic int
obreak(p,uap,retval)3245749Smckusick obreak(p, uap, retval)
3345749Smckusick struct proc *p;
3454915Storek struct obreak_args *uap;
3545749Smckusick int *retval;
3645749Smckusick {
3748386Skarels register struct vmspace *vm = p->p_vmspace;
3845749Smckusick vm_offset_t new, old;
3945749Smckusick int rv;
4045749Smckusick register int diff;
4145749Smckusick
4248386Skarels old = (vm_offset_t)vm->vm_daddr;
4345749Smckusick new = round_page(uap->nsiz);
4448386Skarels if ((int)(new - old) > p->p_rlimit[RLIMIT_DATA].rlim_cur)
4545749Smckusick return(ENOMEM);
4648386Skarels old = round_page(old + ctob(vm->vm_dsize));
4745749Smckusick diff = new - old;
4845749Smckusick if (diff > 0) {
4948386Skarels rv = vm_allocate(&vm->vm_map, &old, diff, FALSE);
5045749Smckusick if (rv != KERN_SUCCESS) {
5145749Smckusick uprintf("sbrk: grow failed, return = %d\n", rv);
5245749Smckusick return(ENOMEM);
5345749Smckusick }
5448386Skarels vm->vm_dsize += btoc(diff);
5545749Smckusick } else if (diff < 0) {
5645749Smckusick diff = -diff;
5748386Skarels rv = vm_deallocate(&vm->vm_map, new, diff);
5845749Smckusick if (rv != KERN_SUCCESS) {
5945749Smckusick uprintf("sbrk: shrink failed, return = %d\n", rv);
6045749Smckusick return(ENOMEM);
6145749Smckusick }
6248386Skarels vm->vm_dsize -= btoc(diff);
6345749Smckusick }
6445749Smckusick return(0);
6545749Smckusick }
6645749Smckusick
6745749Smckusick /*
6848386Skarels * Enlarge the "stack segment" to include the specified
6948386Skarels * stack pointer for the process.
7045749Smckusick */
7153358Sbostic int
grow(p,sp)7248386Skarels grow(p, sp)
7348386Skarels struct proc *p;
74*68164Scgd vm_offset_t sp;
7545749Smckusick {
7648386Skarels register struct vmspace *vm = p->p_vmspace;
7745749Smckusick register int si;
7845749Smckusick
7945749Smckusick /*
8045749Smckusick * For user defined stacks (from sendsig).
8145749Smckusick */
82*68164Scgd if (sp < (vm_offset_t)vm->vm_maxsaddr)
8345749Smckusick return (0);
8445749Smckusick /*
8545749Smckusick * For common case of already allocated (from trap).
8645749Smckusick */
8748386Skarels if (sp >= USRSTACK - ctob(vm->vm_ssize))
8845749Smckusick return (1);
8945749Smckusick /*
9045749Smckusick * Really need to check vs limit and increment stack size if ok.
9145749Smckusick */
9248386Skarels si = clrnd(btoc(USRSTACK-sp) - vm->vm_ssize);
9348386Skarels if (vm->vm_ssize + si > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
9445749Smckusick return (0);
9548386Skarels vm->vm_ssize += si;
9645749Smckusick return (1);
9745749Smckusick }
9845749Smckusick
9954915Storek struct ovadvise_args {
10054915Storek int anom;
10154915Storek };
10245749Smckusick /* ARGSUSED */
10353358Sbostic int
ovadvise(p,uap,retval)10445749Smckusick ovadvise(p, uap, retval)
10545749Smckusick struct proc *p;
10654915Storek struct ovadvise_args *uap;
10745749Smckusick int *retval;
10845749Smckusick {
10945749Smckusick
11048386Skarels return (EINVAL);
11145749Smckusick }
112