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*48386Skarels * @(#)vm_unix.c 7.2 (Berkeley) 04/20/91 1545749Smckusick */ 1645749Smckusick 1745749Smckusick /* 1845749Smckusick * Traditional sbrk/grow interface to VM 1945749Smckusick */ 2045749Smckusick #include "param.h" 2145749Smckusick #include "systm.h" 2245749Smckusick #include "proc.h" 23*48386Skarels #include "resourcevar.h" 2445749Smckusick 25*48386Skarels #include "vm.h" 2645749Smckusick 2745749Smckusick /* ARGSUSED */ 2845749Smckusick obreak(p, uap, retval) 2945749Smckusick struct proc *p; 3045749Smckusick struct args { 3145749Smckusick char *nsiz; 3245749Smckusick } *uap; 3345749Smckusick int *retval; 3445749Smckusick { 35*48386Skarels register struct vmspace *vm = p->p_vmspace; 3645749Smckusick vm_offset_t new, old; 3745749Smckusick int rv; 3845749Smckusick register int diff; 3945749Smckusick 40*48386Skarels old = (vm_offset_t)vm->vm_daddr; 4145749Smckusick new = round_page(uap->nsiz); 42*48386Skarels if ((int)(new - old) > p->p_rlimit[RLIMIT_DATA].rlim_cur) 4345749Smckusick return(ENOMEM); 44*48386Skarels old = round_page(old + ctob(vm->vm_dsize)); 4545749Smckusick diff = new - old; 4645749Smckusick if (diff > 0) { 47*48386Skarels rv = vm_allocate(&vm->vm_map, &old, diff, FALSE); 4845749Smckusick if (rv != KERN_SUCCESS) { 4945749Smckusick uprintf("sbrk: grow failed, return = %d\n", rv); 5045749Smckusick return(ENOMEM); 5145749Smckusick } 52*48386Skarels vm->vm_dsize += btoc(diff); 5345749Smckusick } else if (diff < 0) { 5445749Smckusick diff = -diff; 55*48386Skarels rv = vm_deallocate(&vm->vm_map, new, diff); 5645749Smckusick if (rv != KERN_SUCCESS) { 5745749Smckusick uprintf("sbrk: shrink failed, return = %d\n", rv); 5845749Smckusick return(ENOMEM); 5945749Smckusick } 60*48386Skarels vm->vm_dsize -= btoc(diff); 6145749Smckusick } 6245749Smckusick return(0); 6345749Smckusick } 6445749Smckusick 6545749Smckusick /* 66*48386Skarels * Enlarge the "stack segment" to include the specified 67*48386Skarels * stack pointer for the process. 6845749Smckusick */ 69*48386Skarels grow(p, sp) 70*48386Skarels struct proc *p; 7145749Smckusick unsigned sp; 7245749Smckusick { 73*48386Skarels register struct vmspace *vm = p->p_vmspace; 7445749Smckusick register int si; 7545749Smckusick 7645749Smckusick /* 7745749Smckusick * For user defined stacks (from sendsig). 7845749Smckusick */ 79*48386Skarels if (sp < (unsigned)vm->vm_maxsaddr) 8045749Smckusick return (0); 8145749Smckusick /* 8245749Smckusick * For common case of already allocated (from trap). 8345749Smckusick */ 84*48386Skarels if (sp >= USRSTACK - ctob(vm->vm_ssize)) 8545749Smckusick return (1); 8645749Smckusick /* 8745749Smckusick * Really need to check vs limit and increment stack size if ok. 8845749Smckusick */ 89*48386Skarels si = clrnd(btoc(USRSTACK-sp) - vm->vm_ssize); 90*48386Skarels if (vm->vm_ssize + si > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) 9145749Smckusick return (0); 92*48386Skarels vm->vm_ssize += si; 9345749Smckusick return (1); 9445749Smckusick } 9545749Smckusick 9645749Smckusick /* ARGSUSED */ 9745749Smckusick ovadvise(p, uap, retval) 9845749Smckusick struct proc *p; 9945749Smckusick struct args { 10045749Smckusick int anom; 10145749Smckusick } *uap; 10245749Smckusick int *retval; 10345749Smckusick { 10445749Smckusick 105*48386Skarels return (EINVAL); 10645749Smckusick } 107