145749Smckusick /* 245749Smckusick * Copyright (c) 1988 University of Utah. 345749Smckusick * Copyright (c) 1991 The Regents of the University of California. 445749Smckusick * 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*53358Sbostic * @(#)vm_unix.c 7.3 (Berkeley) 05/04/92 1545749Smckusick */ 1645749Smckusick 1745749Smckusick /* 1845749Smckusick * Traditional sbrk/grow interface to VM 1945749Smckusick */ 20*53358Sbostic #include <sys/param.h> 21*53358Sbostic #include <sys/systm.h> 22*53358Sbostic #include <sys/proc.h> 23*53358Sbostic #include <sys/resourcevar.h> 2445749Smckusick 25*53358Sbostic #include <vm/vm.h> 2645749Smckusick 2745749Smckusick /* ARGSUSED */ 28*53358Sbostic int 2945749Smckusick obreak(p, uap, retval) 3045749Smckusick struct proc *p; 3145749Smckusick struct args { 3245749Smckusick char *nsiz; 3345749Smckusick } *uap; 3445749Smckusick int *retval; 3545749Smckusick { 3648386Skarels register struct vmspace *vm = p->p_vmspace; 3745749Smckusick vm_offset_t new, old; 3845749Smckusick int rv; 3945749Smckusick register int diff; 4045749Smckusick 4148386Skarels old = (vm_offset_t)vm->vm_daddr; 4245749Smckusick new = round_page(uap->nsiz); 4348386Skarels if ((int)(new - old) > p->p_rlimit[RLIMIT_DATA].rlim_cur) 4445749Smckusick return(ENOMEM); 4548386Skarels old = round_page(old + ctob(vm->vm_dsize)); 4645749Smckusick diff = new - old; 4745749Smckusick if (diff > 0) { 4848386Skarels rv = vm_allocate(&vm->vm_map, &old, diff, FALSE); 4945749Smckusick if (rv != KERN_SUCCESS) { 5045749Smckusick uprintf("sbrk: grow failed, return = %d\n", rv); 5145749Smckusick return(ENOMEM); 5245749Smckusick } 5348386Skarels vm->vm_dsize += btoc(diff); 5445749Smckusick } else if (diff < 0) { 5545749Smckusick diff = -diff; 5648386Skarels rv = vm_deallocate(&vm->vm_map, new, diff); 5745749Smckusick if (rv != KERN_SUCCESS) { 5845749Smckusick uprintf("sbrk: shrink failed, return = %d\n", rv); 5945749Smckusick return(ENOMEM); 6045749Smckusick } 6148386Skarels vm->vm_dsize -= btoc(diff); 6245749Smckusick } 6345749Smckusick return(0); 6445749Smckusick } 6545749Smckusick 6645749Smckusick /* 6748386Skarels * Enlarge the "stack segment" to include the specified 6848386Skarels * stack pointer for the process. 6945749Smckusick */ 70*53358Sbostic int 7148386Skarels grow(p, sp) 7248386Skarels struct proc *p; 7345749Smckusick unsigned sp; 7445749Smckusick { 7548386Skarels register struct vmspace *vm = p->p_vmspace; 7645749Smckusick register int si; 7745749Smckusick 7845749Smckusick /* 7945749Smckusick * For user defined stacks (from sendsig). 8045749Smckusick */ 8148386Skarels if (sp < (unsigned)vm->vm_maxsaddr) 8245749Smckusick return (0); 8345749Smckusick /* 8445749Smckusick * For common case of already allocated (from trap). 8545749Smckusick */ 8648386Skarels if (sp >= USRSTACK - ctob(vm->vm_ssize)) 8745749Smckusick return (1); 8845749Smckusick /* 8945749Smckusick * Really need to check vs limit and increment stack size if ok. 9045749Smckusick */ 9148386Skarels si = clrnd(btoc(USRSTACK-sp) - vm->vm_ssize); 9248386Skarels if (vm->vm_ssize + si > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) 9345749Smckusick return (0); 9448386Skarels vm->vm_ssize += si; 9545749Smckusick return (1); 9645749Smckusick } 9745749Smckusick 9845749Smckusick /* ARGSUSED */ 99*53358Sbostic int 10045749Smckusick ovadvise(p, uap, retval) 10145749Smckusick struct proc *p; 10245749Smckusick struct args { 10345749Smckusick int anom; 10445749Smckusick } *uap; 10545749Smckusick int *retval; 10645749Smckusick { 10745749Smckusick 10848386Skarels return (EINVAL); 10945749Smckusick } 110