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$"); 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; 79245296Szont vm_map_t map = &vm->vm_map; 8016679Sdyson vm_offset_t new, old, base; 81244384Szont rlim_t datalim, lmemlim, vmemlim; 82226343Smarcel int prot, rv; 8379224Sdillon int error = 0; 84118771Sbms boolean_t do_map_wirefuture; 851541Srgrimes 86125454Sjhb PROC_LOCK(td->td_proc); 87125454Sjhb datalim = lim_cur(td->td_proc, RLIMIT_DATA); 88244384Szont lmemlim = lim_cur(td->td_proc, RLIMIT_MEMLOCK); 89125454Sjhb vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM); 90125454Sjhb PROC_UNLOCK(td->td_proc); 91125454Sjhb 92118771Sbms do_map_wirefuture = FALSE; 9398460Salc new = round_page((vm_offset_t)uap->nsize); 94245296Szont vm_map_lock(map); 9579224Sdillon 9616679Sdyson base = round_page((vm_offset_t) vm->vm_daddr); 9766748Sdwmalone old = base + ctob(vm->vm_dsize); 9816679Sdyson if (new > base) { 9966748Sdwmalone /* 10098498Salc * Check the resource limit, but allow a process to reduce 10198498Salc * its usage, even if it remains over the limit. 10266748Sdwmalone */ 103125454Sjhb if (new - base > datalim && new > old) { 10479224Sdillon error = ENOMEM; 10579224Sdillon goto done; 10679224Sdillon } 107245296Szont if (new > vm_map_max(map)) { 10879224Sdillon error = ENOMEM; 10979224Sdillon goto done; 11079224Sdillon } 11116679Sdyson } else if (new < base) { 11216679Sdyson /* 11316679Sdyson * This is simply an invalid value. If someone wants to 11416679Sdyson * do fancy address space manipulations, mmap and munmap 11516679Sdyson * can do most of what the user would want. 11616679Sdyson */ 11779224Sdillon error = EINVAL; 11879224Sdillon goto done; 11916679Sdyson } 12016679Sdyson if (new > old) { 121245296Szont if (!old_mlock && map->flags & MAP_WIREFUTURE) { 122245296Szont if (ptoa(pmap_wired_count(map->pmap)) + 123244384Szont (new - old) > lmemlim) { 124244384Szont error = ENOMEM; 125244384Szont goto done; 126244384Szont } 127244384Szont } 128245296Szont if (map->size + (new - old) > vmemlim) { 12998833Sdillon error = ENOMEM; 13098833Sdillon goto done; 13198833Sdillon } 132223825Strasz#ifdef RACCT 133284665Strasz if (racct_enable) { 134284665Strasz PROC_LOCK(td->td_proc); 135284665Strasz error = racct_set(td->td_proc, RACCT_DATA, new - base); 136244384Szont if (error != 0) { 137284665Strasz PROC_UNLOCK(td->td_proc); 138284665Strasz error = ENOMEM; 139284665Strasz goto done; 140284665Strasz } 141284665Strasz error = racct_set(td->td_proc, RACCT_VMEM, 142284665Strasz map->size + (new - old)); 143284665Strasz if (error != 0) { 144244384Szont racct_set_force(td->td_proc, RACCT_DATA, 145244384Szont old - base); 146244384Szont PROC_UNLOCK(td->td_proc); 147244384Szont error = ENOMEM; 148244384Szont goto done; 149244384Szont } 150284665Strasz if (!old_mlock && map->flags & MAP_WIREFUTURE) { 151284665Strasz error = racct_set(td->td_proc, RACCT_MEMLOCK, 152284665Strasz ptoa(pmap_wired_count(map->pmap)) + 153284665Strasz (new - old)); 154284665Strasz if (error != 0) { 155284665Strasz racct_set_force(td->td_proc, RACCT_DATA, 156284665Strasz old - base); 157284665Strasz racct_set_force(td->td_proc, RACCT_VMEM, 158284665Strasz map->size); 159284665Strasz PROC_UNLOCK(td->td_proc); 160284665Strasz error = ENOMEM; 161284665Strasz goto done; 162284665Strasz } 163284665Strasz } 164284665Strasz PROC_UNLOCK(td->td_proc); 165244384Szont } 166223825Strasz#endif 167226343Smarcel prot = VM_PROT_RW; 168226343Smarcel#ifdef COMPAT_FREEBSD32 169226343Smarcel#if defined(__amd64__) || defined(__ia64__) 170226388Skib if (i386_read_exec && SV_PROC_FLAG(td->td_proc, SV_ILP32)) 171226343Smarcel prot |= VM_PROT_EXECUTE; 172226343Smarcel#endif 173226343Smarcel#endif 174245296Szont rv = vm_map_insert(map, NULL, 0, old, new, prot, VM_PROT_ALL, 0); 1751541Srgrimes if (rv != KERN_SUCCESS) { 176223825Strasz#ifdef RACCT 177284665Strasz if (racct_enable) { 178284665Strasz PROC_LOCK(td->td_proc); 179284665Strasz racct_set_force(td->td_proc, 180284665Strasz RACCT_DATA, old - base); 181284665Strasz racct_set_force(td->td_proc, 182284665Strasz RACCT_VMEM, map->size); 183284665Strasz if (!old_mlock && map->flags & MAP_WIREFUTURE) { 184284665Strasz racct_set_force(td->td_proc, 185284665Strasz RACCT_MEMLOCK, 186284665Strasz ptoa(pmap_wired_count(map->pmap))); 187284665Strasz } 188284665Strasz PROC_UNLOCK(td->td_proc); 189244384Szont } 190223825Strasz#endif 19179224Sdillon error = ENOMEM; 19279224Sdillon goto done; 1931541Srgrimes } 19498460Salc vm->vm_dsize += btoc(new - old); 195118771Sbms /* 196118771Sbms * Handle the MAP_WIREFUTURE case for legacy applications, 197118771Sbms * by marking the newly mapped range of pages as wired. 198118771Sbms * We are not required to perform a corresponding 199118771Sbms * vm_map_unwire() before vm_map_delete() below, as 200118771Sbms * it will forcibly unwire the pages in the range. 201118771Sbms * 202118771Sbms * XXX If the pages cannot be wired, no error is returned. 203118771Sbms */ 204245296Szont if ((map->flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) { 205118771Sbms if (bootverbose) 206118771Sbms printf("obreak: MAP_WIREFUTURE set\n"); 207118771Sbms do_map_wirefuture = TRUE; 208118771Sbms } 20916679Sdyson } else if (new < old) { 210245296Szont rv = vm_map_delete(map, new, old); 2111541Srgrimes if (rv != KERN_SUCCESS) { 21279224Sdillon error = ENOMEM; 21379224Sdillon goto done; 2141541Srgrimes } 21516679Sdyson vm->vm_dsize -= btoc(old - new); 216223825Strasz#ifdef RACCT 217284665Strasz if (racct_enable) { 218284665Strasz PROC_LOCK(td->td_proc); 219284665Strasz racct_set_force(td->td_proc, RACCT_DATA, new - base); 220284665Strasz racct_set_force(td->td_proc, RACCT_VMEM, map->size); 221284665Strasz if (!old_mlock && map->flags & MAP_WIREFUTURE) { 222284665Strasz racct_set_force(td->td_proc, RACCT_MEMLOCK, 223284665Strasz ptoa(pmap_wired_count(map->pmap))); 224284665Strasz } 225284665Strasz PROC_UNLOCK(td->td_proc); 226244384Szont } 227223825Strasz#endif 2281541Srgrimes } 22979224Sdillondone: 230245296Szont vm_map_unlock(map); 231118771Sbms 232118771Sbms if (do_map_wirefuture) 233245296Szont (void) vm_map_wire(map, old, new, 234118771Sbms VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); 235118771Sbms 23679224Sdillon return (error); 2371541Srgrimes} 2381541Srgrimes 23912221Sbde#ifndef _SYS_SYSPROTO_H_ 2401541Srgrimesstruct ovadvise_args { 2415455Sdg int anom; 2421541Srgrimes}; 24312221Sbde#endif 2441549Srgrimes 24582697Sdillon/* 24682697Sdillon * MPSAFE 24782697Sdillon */ 2481541Srgrimes/* ARGSUSED */ 2491541Srgrimesint 250225617Skmacysys_ovadvise(td, uap) 25183366Sjulian struct thread *td; 2521541Srgrimes struct ovadvise_args *uap; 2531541Srgrimes{ 25479224Sdillon /* START_GIANT_OPTIONAL */ 25579224Sdillon /* END_GIANT_OPTIONAL */ 2561541Srgrimes return (EINVAL); 2571541Srgrimes} 258