vm_unix.c revision 76827
154359Sroberto/* 254359Sroberto * Copyright (c) 1988 University of Utah. 354359Sroberto * Copyright (c) 1991, 1993 454359Sroberto * The Regents of the University of California. All rights reserved. 554359Sroberto * 654359Sroberto * This code is derived from software contributed to Berkeley by 754359Sroberto * the Systems Programming Group of the University of Utah Computer 854359Sroberto * Science Department. 954359Sroberto * 1082498Sroberto * Redistribution and use in source and binary forms, with or without 1182498Sroberto * modification, are permitted provided that the following conditions 1282498Sroberto * are met: 1382498Sroberto * 1. Redistributions of source code must retain the above copyright 1482498Sroberto * notice, this list of conditions and the following disclaimer. 1582498Sroberto * 2. Redistributions in binary form must reproduce the above copyright 1654359Sroberto * notice, this list of conditions and the following disclaimer in the 1754359Sroberto * documentation and/or other materials provided with the distribution. 1854359Sroberto * 3. All advertising materials mentioning features or use of this software 1954359Sroberto * must display the following acknowledgement: 2054359Sroberto * This product includes software developed by the University of 2154359Sroberto * California, Berkeley and its contributors. 2254359Sroberto * 4. Neither the name of the University nor the names of its contributors 2356746Sroberto * may be used to endorse or promote products derived from this software 2454359Sroberto * without specific prior written permission. 2554359Sroberto * 2654359Sroberto * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2754359Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2854359Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2954359Sroberto * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3054359Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3154359Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3254359Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3354359Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3454359Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3554359Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3654359Sroberto * SUCH DAMAGE. 3754359Sroberto * 3854359Sroberto * from: Utah $Hdr: vm_unix.c 1.1 89/11/07$ 3954359Sroberto * 4054359Sroberto * @(#)vm_unix.c 8.1 (Berkeley) 6/11/93 4154359Sroberto * $FreeBSD: head/sys/vm/vm_unix.c 76827 2001-05-19 01:28:09Z alfred $ 4254359Sroberto */ 4354359Sroberto 4454359Sroberto/* 4554359Sroberto * Traditional sbrk/grow interface to VM 4654359Sroberto */ 4754359Sroberto#include <sys/param.h> 4854359Sroberto#include <sys/lock.h> 4954359Sroberto#include <sys/sysproto.h> 5054359Sroberto#include <sys/proc.h> 5154359Sroberto#include <sys/resourcevar.h> 5254359Sroberto#include <sys/lock.h> 5354359Sroberto#include <sys/mutex.h> 5454359Sroberto#include <sys/systm.h> 5554359Sroberto 5654359Sroberto#include <vm/vm.h> 5754359Sroberto#include <vm/vm_param.h> 5854359Sroberto#include <vm/pmap.h> 5954359Sroberto#include <vm/vm_map.h> 6054359Sroberto 6154359Sroberto#ifndef _SYS_SYSPROTO_H_ 6254359Srobertostruct obreak_args { 6354359Sroberto char *nsize; 6454359Sroberto}; 6554359Sroberto#endif 6654359Sroberto 6754359Sroberto/* ARGSUSED */ 6854359Srobertoint 6954359Srobertoobreak(p, uap) 7054359Sroberto struct proc *p; 7154359Sroberto struct obreak_args *uap; 7254359Sroberto{ 7354359Sroberto register struct vmspace *vm = p->p_vmspace; 7454359Sroberto vm_offset_t new, old, base; 7554359Sroberto int rv; 7654359Sroberto 7754359Sroberto base = round_page((vm_offset_t) vm->vm_daddr); 7854359Sroberto new = round_page((vm_offset_t)uap->nsize); 7954359Sroberto old = base + ctob(vm->vm_dsize); 8054359Sroberto if (new > base) { 8154359Sroberto /* 8254359Sroberto * We check resource limits here, but alow processes to 8354359Sroberto * reduce their usage, even if they remain over the limit. 8454359Sroberto */ 8554359Sroberto if (new > old && 8654359Sroberto (new - base) > (unsigned) p->p_rlimit[RLIMIT_DATA].rlim_cur) 8754359Sroberto return ENOMEM; 8854359Sroberto if (new >= VM_MAXUSER_ADDRESS) 8954359Sroberto return (ENOMEM); 9054359Sroberto } else if (new < base) { 9154359Sroberto /* 9254359Sroberto * This is simply an invalid value. If someone wants to 9354359Sroberto * do fancy address space manipulations, mmap and munmap 9454359Sroberto * can do most of what the user would want. 9554359Sroberto */ 9654359Sroberto return EINVAL; 9754359Sroberto } 9854359Sroberto 9954359Sroberto mtx_lock(&vm_mtx); 10054359Sroberto if (new > old) { 10154359Sroberto vm_size_t diff; 10254359Sroberto 10354359Sroberto diff = new - old; 10454359Sroberto rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE, 10554359Sroberto VM_PROT_ALL, VM_PROT_ALL, 0); 10654359Sroberto if (rv != KERN_SUCCESS) { 10754359Sroberto mtx_unlock(&vm_mtx); 10854359Sroberto return (ENOMEM); 10954359Sroberto } 11054359Sroberto vm->vm_dsize += btoc(diff); 11154359Sroberto } else if (new < old) { 11254359Sroberto rv = vm_map_remove(&vm->vm_map, new, old); 11354359Sroberto if (rv != KERN_SUCCESS) { 11454359Sroberto mtx_unlock(&vm_mtx); 11554359Sroberto return (ENOMEM); 11654359Sroberto } 11754359Sroberto vm->vm_dsize -= btoc(old - new); 11854359Sroberto } 11954359Sroberto mtx_unlock(&vm_mtx); 12054359Sroberto return (0); 12154359Sroberto} 12254359Sroberto 12354359Sroberto#ifndef _SYS_SYSPROTO_H_ 12454359Srobertostruct ovadvise_args { 12554359Sroberto int anom; 12654359Sroberto}; 12754359Sroberto#endif 12854359Sroberto 12954359Sroberto/* ARGSUSED */ 13054359Srobertoint 13154359Srobertoovadvise(p, uap) 13254359Sroberto struct proc *p; 13354359Sroberto struct ovadvise_args *uap; 13454359Sroberto{ 13554359Sroberto 13654359Sroberto return (EINVAL); 13754359Sroberto} 13854359Sroberto