vm_unix.c revision 244384
1139825Simp/*- 21541Srgrimes * Copyright (c) 1988 University of Utah. 31541Srgrimes * Copyright (c) 1991, 1993 41541Srgrimes * The Regents of the University of California. All rights reserved. 51541Srgrimes * 61541Srgrimes * This code is derived from software contributed to Berkeley by 71541Srgrimes * the Systems Programming Group of the University of Utah Computer 81541Srgrimes * Science Department. 91541Srgrimes * 101541Srgrimes * Redistribution and use in source and binary forms, with or without 111541Srgrimes * modification, are permitted provided that the following conditions 121541Srgrimes * are met: 131541Srgrimes * 1. Redistributions of source code must retain the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer. 151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161541Srgrimes * notice, this list of conditions and the following disclaimer in the 171541Srgrimes * documentation and/or other materials provided with the distribution. 181541Srgrimes * 4. Neither the name of the University nor the names of its contributors 191541Srgrimes * may be used to endorse or promote products derived from this software 201541Srgrimes * without specific prior written permission. 211541Srgrimes * 221541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321541Srgrimes * SUCH DAMAGE. 331541Srgrimes * 341541Srgrimes * from: Utah $Hdr: vm_unix.c 1.1 89/11/07$ 351541Srgrimes * 361541Srgrimes * @(#)vm_unix.c 8.1 (Berkeley) 6/11/93 371541Srgrimes */ 381541Srgrimes 39226343Smarcel#include "opt_compat.h" 40226343Smarcel 411541Srgrimes/* 421541Srgrimes * Traditional sbrk/grow interface to VM 431541Srgrimes */ 4477139Sjhb 45116226Sobrien#include <sys/cdefs.h> 46116226Sobrien__FBSDID("$FreeBSD: head/sys/vm/vm_unix.c 244384 2012-12-18 07:35:01Z zont $"); 47116226Sobrien 481541Srgrimes#include <sys/param.h> 4976166Smarkm#include <sys/lock.h> 5076981Sjhb#include <sys/mutex.h> 511541Srgrimes#include <sys/proc.h> 52220373Strasz#include <sys/racct.h> 531541Srgrimes#include <sys/resourcevar.h> 54226343Smarcel#include <sys/sysent.h> 5576981Sjhb#include <sys/sysproto.h> 5676827Salfred#include <sys/systm.h> 571541Srgrimes 581541Srgrimes#include <vm/vm.h> 5912662Sdg#include <vm/vm_param.h> 6012662Sdg#include <vm/pmap.h> 6112662Sdg#include <vm/vm_map.h> 621541Srgrimes 6312221Sbde#ifndef _SYS_SYSPROTO_H_ 641541Srgrimesstruct obreak_args { 6512206Sbde char *nsize; 661541Srgrimes}; 6712221Sbde#endif 681549Srgrimes 6982697Sdillon/* 7082697Sdillon * MPSAFE 7182697Sdillon */ 721541Srgrimes/* ARGSUSED */ 731541Srgrimesint 74225617Skmacysys_obreak(td, uap) 7583366Sjulian struct thread *td; 761541Srgrimes struct obreak_args *uap; 771541Srgrimes{ 7883366Sjulian struct vmspace *vm = td->td_proc->p_vmspace; 7916679Sdyson vm_offset_t new, old, base; 80244384Szont rlim_t datalim, lmemlim, vmemlim; 81226343Smarcel int prot, rv; 8279224Sdillon int error = 0; 83118771Sbms boolean_t do_map_wirefuture; 841541Srgrimes 85125454Sjhb PROC_LOCK(td->td_proc); 86125454Sjhb datalim = lim_cur(td->td_proc, RLIMIT_DATA); 87244384Szont lmemlim = lim_cur(td->td_proc, RLIMIT_MEMLOCK); 88125454Sjhb vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM); 89125454Sjhb PROC_UNLOCK(td->td_proc); 90125454Sjhb 91118771Sbms do_map_wirefuture = FALSE; 9298460Salc new = round_page((vm_offset_t)uap->nsize); 9398460Salc vm_map_lock(&vm->vm_map); 9479224Sdillon 9516679Sdyson base = round_page((vm_offset_t) vm->vm_daddr); 9666748Sdwmalone old = base + ctob(vm->vm_dsize); 9716679Sdyson if (new > base) { 9866748Sdwmalone /* 9998498Salc * Check the resource limit, but allow a process to reduce 10098498Salc * its usage, even if it remains over the limit. 10166748Sdwmalone */ 102125454Sjhb if (new - base > datalim && new > old) { 10379224Sdillon error = ENOMEM; 10479224Sdillon goto done; 10579224Sdillon } 106103767Sjake if (new > vm_map_max(&vm->vm_map)) { 10779224Sdillon error = ENOMEM; 10879224Sdillon goto done; 10979224Sdillon } 11016679Sdyson } else if (new < base) { 11116679Sdyson /* 11216679Sdyson * This is simply an invalid value. If someone wants to 11316679Sdyson * do fancy address space manipulations, mmap and munmap 11416679Sdyson * can do most of what the user would want. 11516679Sdyson */ 11679224Sdillon error = EINVAL; 11779224Sdillon goto done; 11816679Sdyson } 11916679Sdyson if (new > old) { 120244384Szont if (!old_mlock && vm->vm_map.flags & MAP_WIREFUTURE) { 121244384Szont if (ptoa(vmspace_wired_count(td->td_proc->p_vmspace)) + 122244384Szont (new - old) > lmemlim) { 123244384Szont error = ENOMEM; 124244384Szont goto done; 125244384Szont } 126244384Szont } 127125454Sjhb if (vm->vm_map.size + (new - old) > vmemlim) { 12898833Sdillon error = ENOMEM; 12998833Sdillon goto done; 13098833Sdillon } 131223825Strasz#ifdef RACCT 132220373Strasz PROC_LOCK(td->td_proc); 133220373Strasz error = racct_set(td->td_proc, RACCT_DATA, new - base); 134220373Strasz if (error != 0) { 135220373Strasz PROC_UNLOCK(td->td_proc); 136220373Strasz error = ENOMEM; 137220373Strasz goto done; 138220373Strasz } 139220373Strasz error = racct_set(td->td_proc, RACCT_VMEM, 140220373Strasz vm->vm_map.size + (new - old)); 141220373Strasz if (error != 0) { 142220373Strasz racct_set_force(td->td_proc, RACCT_DATA, old - base); 143220373Strasz PROC_UNLOCK(td->td_proc); 144220373Strasz error = ENOMEM; 145220373Strasz goto done; 146220373Strasz } 147244384Szont if (!old_mlock && vm->vm_map.flags & MAP_WIREFUTURE) { 148244384Szont error = racct_set(td->td_proc, RACCT_MEMLOCK, 149244384Szont ptoa(vmspace_wired_count(td->td_proc->p_vmspace)) + 150244384Szont (new - old)); 151244384Szont if (error != 0) { 152244384Szont racct_set_force(td->td_proc, RACCT_DATA, 153244384Szont old - base); 154244384Szont racct_set_force(td->td_proc, RACCT_VMEM, 155244384Szont vm->vm_map.size); 156244384Szont PROC_UNLOCK(td->td_proc); 157244384Szont error = ENOMEM; 158244384Szont goto done; 159244384Szont } 160244384Szont } 161220373Strasz PROC_UNLOCK(td->td_proc); 162223825Strasz#endif 163226343Smarcel prot = VM_PROT_RW; 164226343Smarcel#ifdef COMPAT_FREEBSD32 165226343Smarcel#if defined(__amd64__) || defined(__ia64__) 166226388Skib if (i386_read_exec && SV_PROC_FLAG(td->td_proc, SV_ILP32)) 167226343Smarcel prot |= VM_PROT_EXECUTE; 168226343Smarcel#endif 169226343Smarcel#endif 17098460Salc rv = vm_map_insert(&vm->vm_map, NULL, 0, old, new, 171226343Smarcel prot, VM_PROT_ALL, 0); 1721541Srgrimes if (rv != KERN_SUCCESS) { 173223825Strasz#ifdef RACCT 174220373Strasz PROC_LOCK(td->td_proc); 175220373Strasz racct_set_force(td->td_proc, RACCT_DATA, old - base); 176220373Strasz racct_set_force(td->td_proc, RACCT_VMEM, vm->vm_map.size); 177244384Szont if (!old_mlock && vm->vm_map.flags & MAP_WIREFUTURE) { 178244384Szont racct_set_force(td->td_proc, RACCT_MEMLOCK, 179244384Szont ptoa(vmspace_wired_count( 180244384Szont td->td_proc->p_vmspace))); 181244384Szont } 182220373Strasz PROC_UNLOCK(td->td_proc); 183223825Strasz#endif 18479224Sdillon error = ENOMEM; 18579224Sdillon goto done; 1861541Srgrimes } 18798460Salc vm->vm_dsize += btoc(new - old); 188118771Sbms /* 189118771Sbms * Handle the MAP_WIREFUTURE case for legacy applications, 190118771Sbms * by marking the newly mapped range of pages as wired. 191118771Sbms * We are not required to perform a corresponding 192118771Sbms * vm_map_unwire() before vm_map_delete() below, as 193118771Sbms * it will forcibly unwire the pages in the range. 194118771Sbms * 195118771Sbms * XXX If the pages cannot be wired, no error is returned. 196118771Sbms */ 197118771Sbms if ((vm->vm_map.flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) { 198118771Sbms if (bootverbose) 199118771Sbms printf("obreak: MAP_WIREFUTURE set\n"); 200118771Sbms do_map_wirefuture = TRUE; 201118771Sbms } 20216679Sdyson } else if (new < old) { 203189015Skib rv = vm_map_delete(&vm->vm_map, new, old); 2041541Srgrimes if (rv != KERN_SUCCESS) { 20579224Sdillon error = ENOMEM; 20679224Sdillon goto done; 2071541Srgrimes } 20816679Sdyson vm->vm_dsize -= btoc(old - new); 209223825Strasz#ifdef RACCT 210220373Strasz PROC_LOCK(td->td_proc); 211220373Strasz racct_set_force(td->td_proc, RACCT_DATA, new - base); 212220373Strasz racct_set_force(td->td_proc, RACCT_VMEM, vm->vm_map.size); 213244384Szont if (!old_mlock && vm->vm_map.flags & MAP_WIREFUTURE) { 214244384Szont racct_set_force(td->td_proc, RACCT_MEMLOCK, 215244384Szont ptoa(vmspace_wired_count(td->td_proc->p_vmspace))); 216244384Szont } 217220373Strasz PROC_UNLOCK(td->td_proc); 218223825Strasz#endif 2191541Srgrimes } 22079224Sdillondone: 22198460Salc vm_map_unlock(&vm->vm_map); 222118771Sbms 223118771Sbms if (do_map_wirefuture) 224118771Sbms (void) vm_map_wire(&vm->vm_map, old, new, 225118771Sbms VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); 226118771Sbms 22779224Sdillon return (error); 2281541Srgrimes} 2291541Srgrimes 23012221Sbde#ifndef _SYS_SYSPROTO_H_ 2311541Srgrimesstruct ovadvise_args { 2325455Sdg int anom; 2331541Srgrimes}; 23412221Sbde#endif 2351549Srgrimes 23682697Sdillon/* 23782697Sdillon * MPSAFE 23882697Sdillon */ 2391541Srgrimes/* ARGSUSED */ 2401541Srgrimesint 241225617Skmacysys_ovadvise(td, uap) 24283366Sjulian struct thread *td; 2431541Srgrimes struct ovadvise_args *uap; 2441541Srgrimes{ 24579224Sdillon /* START_GIANT_OPTIONAL */ 24679224Sdillon /* END_GIANT_OPTIONAL */ 2471541Srgrimes return (EINVAL); 2481541Srgrimes} 249