vm_unix.c revision 189015
1139826Simp/*- 253541Sshin * Copyright (c) 1988 University of Utah. 353541Sshin * Copyright (c) 1991, 1993 453541Sshin * The Regents of the University of California. All rights reserved. 553541Sshin * 653541Sshin * This code is derived from software contributed to Berkeley by 753541Sshin * the Systems Programming Group of the University of Utah Computer 853541Sshin * Science Department. 953541Sshin * 1053541Sshin * Redistribution and use in source and binary forms, with or without 1153541Sshin * modification, are permitted provided that the following conditions 1253541Sshin * are met: 1353541Sshin * 1. Redistributions of source code must retain the above copyright 1453541Sshin * notice, this list of conditions and the following disclaimer. 1553541Sshin * 2. Redistributions in binary form must reproduce the above copyright 1653541Sshin * notice, this list of conditions and the following disclaimer in the 1753541Sshin * documentation and/or other materials provided with the distribution. 1853541Sshin * 4. Neither the name of the University nor the names of its contributors 1953541Sshin * may be used to endorse or promote products derived from this software 2053541Sshin * without specific prior written permission. 2153541Sshin * 2253541Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2353541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2453541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2553541Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2653541Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2753541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28174510Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29174510Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3053541Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3153541Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32174510Sobrien * SUCH DAMAGE. 33174510Sobrien * 34174510Sobrien * from: Utah $Hdr: vm_unix.c 1.1 89/11/07$ 3562587Sitojun * 3662587Sitojun * @(#)vm_unix.c 8.1 (Berkeley) 6/11/93 3762587Sitojun */ 3853541Sshin 3953541Sshin/* 4053541Sshin * Traditional sbrk/grow interface to VM 4153541Sshin */ 42303458Ssbruno 4353541Sshin#include <sys/cdefs.h> 4453541Sshin__FBSDID("$FreeBSD: head/sys/vm/vm_unix.c 189015 2009-02-24 20:57:43Z kib $"); 4553541Sshin 4678064Sume#include <sys/param.h> 47185751Simp#include <sys/lock.h> 4853541Sshin#include <sys/mutex.h> 49185747Skmacy#include <sys/proc.h> 5053541Sshin#include <sys/resourcevar.h> 5178064Sume#include <sys/sysproto.h> 5253541Sshin#include <sys/systm.h> 5353541Sshin 5453541Sshin#include <vm/vm.h> 5553541Sshin#include <vm/vm_param.h> 5653541Sshin#include <vm/pmap.h> 5753541Sshin#include <vm/vm_map.h> 58185571Sbz 5953541Sshin#ifndef _SYS_SYSPROTO_H_ 6053541Sshinstruct obreak_args { 61186119Sqingli char *nsize; 6253541Sshin}; 6378064Sume#endif 6462587Sitojun 6553541Sshin/* 6653541Sshin * MPSAFE 6762587Sitojun */ 6862587Sitojun/* ARGSUSED */ 6953541Sshinint 70175162Sobrienobreak(td, uap) 71175162Sobrien struct thread *td; 72241916Sdelphij struct obreak_args *uap; 73241916Sdelphij{ 74241916Sdelphij struct vmspace *vm = td->td_proc->p_vmspace; 75241916Sdelphij vm_offset_t new, old, base; 76241916Sdelphij rlim_t datalim, vmemlim; 77175162Sobrien int rv; 78175162Sobrien int error = 0; 7962587Sitojun boolean_t do_map_wirefuture; 80175162Sobrien 81175162Sobrien PROC_LOCK(td->td_proc); 82175162Sobrien datalim = lim_cur(td->td_proc, RLIMIT_DATA); 8353541Sshin vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM); 84175162Sobrien PROC_UNLOCK(td->td_proc); 85241916Sdelphij 86241916Sdelphij do_map_wirefuture = FALSE; 8753541Sshin new = round_page((vm_offset_t)uap->nsize); 88229547Sbz vm_map_lock(&vm->vm_map); 89229547Sbz 90229547Sbz base = round_page((vm_offset_t) vm->vm_daddr); 91175162Sobrien old = base + ctob(vm->vm_dsize); 9253541Sshin if (new > base) { 93195699Srwatson /* 94195727Srwatson * Check the resource limit, but allow a process to reduce 9553541Sshin * its usage, even if it remains over the limit. 96215701Sdim */ 97207369Sbz if (new - base > datalim && new > old) { 98195727Srwatson error = ENOMEM; 9962587Sitojun goto done; 100207369Sbz } 101207369Sbz if (new > vm_map_max(&vm->vm_map)) { 102195699Srwatson error = ENOMEM; 103207369Sbz goto done; 104207369Sbz } 10578064Sume } else if (new < base) { 106207369Sbz /* 107207369Sbz * This is simply an invalid value. If someone wants to 108151539Ssuz * do fancy address space manipulations, mmap and munmap 109151539Ssuz * can do most of what the user would want. 110151539Ssuz */ 111151539Ssuz error = EINVAL; 112151539Ssuz goto done; 113151539Ssuz } 114151539Ssuz if (new > old) { 11578064Sume if (vm->vm_map.size + (new - old) > vmemlim) { 11653541Sshin error = ENOMEM; 11753541Sshin goto done; 11853541Sshin } 11953541Sshin rv = vm_map_insert(&vm->vm_map, NULL, 0, old, new, 12053541Sshin VM_PROT_ALL, VM_PROT_ALL, 0); 12153541Sshin if (rv != KERN_SUCCESS) { 12253541Sshin error = ENOMEM; 123171259Sdelphij goto done; 12453541Sshin } 12553541Sshin vm->vm_dsize += btoc(new - old); 12653541Sshin /* 12762587Sitojun * Handle the MAP_WIREFUTURE case for legacy applications, 12853541Sshin * by marking the newly mapped range of pages as wired. 12953541Sshin * We are not required to perform a corresponding 13053541Sshin * vm_map_unwire() before vm_map_delete() below, as 13153541Sshin * it will forcibly unwire the pages in the range. 132165118Sbz * 13353541Sshin * XXX If the pages cannot be wired, no error is returned. 134222728Shrs */ 135222728Shrs if ((vm->vm_map.flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) { 136222728Shrs if (bootverbose) 137222728Shrs printf("obreak: MAP_WIREFUTURE set\n"); 138222728Shrs do_map_wirefuture = TRUE; 13962587Sitojun } 14053541Sshin } else if (new < old) { 14153541Sshin rv = vm_map_delete(&vm->vm_map, new, old); 14253541Sshin if (rv != KERN_SUCCESS) { 14378064Sume error = ENOMEM; 14478064Sume goto done; 145165118Sbz } 146165118Sbz vm->vm_dsize -= btoc(old - new); 14778064Sume } 14853541Sshindone: 14953541Sshin vm_map_unlock(&vm->vm_map); 15053541Sshin 15153541Sshin if (do_map_wirefuture) 15253541Sshin (void) vm_map_wire(&vm->vm_map, old, new, 15353541Sshin VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); 15453541Sshin 15562587Sitojun return (error); 15662587Sitojun} 15762587Sitojun 15862587Sitojun#ifndef _SYS_SYSPROTO_H_ 15962587Sitojunstruct ovadvise_args { 16062587Sitojun int anom; 16162587Sitojun}; 16262587Sitojun#endif 163190964Srwatson 16453541Sshin/* 16562587Sitojun * MPSAFE 16662587Sitojun */ 16753541Sshin/* ARGSUSED */ 16853541Sshinint 16953541Sshinovadvise(td, uap) 17053541Sshin struct thread *td; 17178064Sume struct ovadvise_args *uap; 17278064Sume{ 17378064Sume /* START_GIANT_OPTIONAL */ 17462587Sitojun /* END_GIANT_OPTIONAL */ 17553541Sshin return (EINVAL); 17653541Sshin} 17753541Sshin