vm_unix.c revision 125454
1251881Speter/*
2251881Speter * Copyright (c) 1988 University of Utah.
3251881Speter * Copyright (c) 1991, 1993
4251881Speter *	The Regents of the University of California.  All rights reserved.
5251881Speter *
6251881Speter * This code is derived from software contributed to Berkeley by
7251881Speter * the Systems Programming Group of the University of Utah Computer
8251881Speter * Science Department.
9251881Speter *
10251881Speter * Redistribution and use in source and binary forms, with or without
11251881Speter * modification, are permitted provided that the following conditions
12251881Speter * are met:
13251881Speter * 1. Redistributions of source code must retain the above copyright
14251881Speter *    notice, this list of conditions and the following disclaimer.
15251881Speter * 2. Redistributions in binary form must reproduce the above copyright
16251881Speter *    notice, this list of conditions and the following disclaimer in the
17251881Speter *    documentation and/or other materials provided with the distribution.
18251881Speter * 3. All advertising materials mentioning features or use of this software
19251881Speter *    must display the following acknowledgement:
20251881Speter *	This product includes software developed by the University of
21251881Speter *	California, Berkeley and its contributors.
22251881Speter * 4. Neither the name of the University nor the names of its contributors
23251881Speter *    may be used to endorse or promote products derived from this software
24251881Speter *    without specific prior written permission.
25251881Speter *
26251881Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27251881Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28251881Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29251881Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30251881Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31251881Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32251881Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33251881Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34251881Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35251881Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36251881Speter * SUCH DAMAGE.
37251881Speter *
38251881Speter * from: Utah $Hdr: vm_unix.c 1.1 89/11/07$
39251881Speter *
40251881Speter *	@(#)vm_unix.c	8.1 (Berkeley) 6/11/93
41251881Speter */
42251881Speter
43251881Speter/*
44251881Speter * Traditional sbrk/grow interface to VM
45251881Speter */
46251881Speter
47251881Speter#include <sys/cdefs.h>
48251881Speter__FBSDID("$FreeBSD: head/sys/vm/vm_unix.c 125454 2004-02-04 21:52:57Z jhb $");
49251881Speter
50251881Speter#include <sys/param.h>
51251881Speter#include <sys/lock.h>
52251881Speter#include <sys/mutex.h>
53251881Speter#include <sys/proc.h>
54251881Speter#include <sys/resourcevar.h>
55251881Speter#include <sys/sysproto.h>
56251881Speter#include <sys/systm.h>
57251881Speter
58251881Speter#include <vm/vm.h>
59251881Speter#include <vm/vm_param.h>
60251881Speter#include <vm/pmap.h>
61251881Speter#include <vm/vm_map.h>
62251881Speter
63251881Speter#ifndef _SYS_SYSPROTO_H_
64251881Speterstruct obreak_args {
65251881Speter	char *nsize;
66251881Speter};
67251881Speter#endif
68251881Speter
69251881Speter/*
70251881Speter * MPSAFE
71251881Speter */
72251881Speter/* ARGSUSED */
73251881Speterint
74251881Speterobreak(td, uap)
75251881Speter	struct thread *td;
76251881Speter	struct obreak_args *uap;
77251881Speter{
78251881Speter	struct vmspace *vm = td->td_proc->p_vmspace;
79251881Speter	vm_offset_t new, old, base;
80251881Speter	rlim_t datalim, vmemlim;
81251881Speter	int rv;
82251881Speter	int error = 0;
83251881Speter	boolean_t do_map_wirefuture;
84251881Speter
85251881Speter	PROC_LOCK(td->td_proc);
86251881Speter	datalim = lim_cur(td->td_proc, RLIMIT_DATA);
87251881Speter	vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM);
88251881Speter	PROC_UNLOCK(td->td_proc);
89251881Speter
90251881Speter	do_map_wirefuture = FALSE;
91251881Speter	new = round_page((vm_offset_t)uap->nsize);
92251881Speter	vm_map_lock(&vm->vm_map);
93251881Speter
94251881Speter	base = round_page((vm_offset_t) vm->vm_daddr);
95251881Speter	old = base + ctob(vm->vm_dsize);
96251881Speter	if (new > base) {
97251881Speter		/*
98251881Speter		 * Check the resource limit, but allow a process to reduce
99251881Speter		 * its usage, even if it remains over the limit.
100251881Speter		 */
101251881Speter		if (new - base > datalim && new > old) {
102251881Speter			error = ENOMEM;
103251881Speter			goto done;
104251881Speter		}
105251881Speter		if (new > vm_map_max(&vm->vm_map)) {
106251881Speter			error = ENOMEM;
107251881Speter			goto done;
108251881Speter		}
109251881Speter	} else if (new < base) {
110251881Speter		/*
111251881Speter		 * This is simply an invalid value.  If someone wants to
112251881Speter		 * do fancy address space manipulations, mmap and munmap
113251881Speter		 * can do most of what the user would want.
114251881Speter		 */
115251881Speter		error = EINVAL;
116251881Speter		goto done;
117251881Speter	}
118251881Speter	if (new > old) {
119251881Speter		if (vm->vm_map.size + (new - old) > vmemlim) {
120251881Speter			error = ENOMEM;
121251881Speter			goto done;
122251881Speter		}
123251881Speter		rv = vm_map_insert(&vm->vm_map, NULL, 0, old, new,
124251881Speter		    VM_PROT_ALL, VM_PROT_ALL, 0);
125251881Speter		if (rv != KERN_SUCCESS) {
126251881Speter			error = ENOMEM;
127251881Speter			goto done;
128251881Speter		}
129251881Speter		vm->vm_dsize += btoc(new - old);
130251881Speter		/*
131251881Speter		 * Handle the MAP_WIREFUTURE case for legacy applications,
132251881Speter		 * by marking the newly mapped range of pages as wired.
133251881Speter		 * We are not required to perform a corresponding
134251881Speter		 * vm_map_unwire() before vm_map_delete() below, as
135251881Speter		 * it will forcibly unwire the pages in the range.
136251881Speter		 *
137251881Speter		 * XXX If the pages cannot be wired, no error is returned.
138251881Speter		 */
139251881Speter		if ((vm->vm_map.flags & MAP_WIREFUTURE) == MAP_WIREFUTURE) {
140251881Speter			if (bootverbose)
141251881Speter				printf("obreak: MAP_WIREFUTURE set\n");
142251881Speter			do_map_wirefuture = TRUE;
143251881Speter		}
144251881Speter	} else if (new < old) {
145251881Speter		rv = vm_map_delete(&vm->vm_map, new, old);
146251881Speter		if (rv != KERN_SUCCESS) {
147251881Speter			error = ENOMEM;
148251881Speter			goto done;
149251881Speter		}
150251881Speter		vm->vm_dsize -= btoc(old - new);
151251881Speter	}
152251881Speterdone:
153251881Speter	vm_map_unlock(&vm->vm_map);
154251881Speter
155251881Speter	if (do_map_wirefuture)
156251881Speter		(void) vm_map_wire(&vm->vm_map, old, new,
157251881Speter		    VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES);
158251881Speter
159251881Speter	return (error);
160251881Speter}
161251881Speter
162251881Speter#ifndef _SYS_SYSPROTO_H_
163251881Speterstruct ovadvise_args {
164251881Speter	int anom;
165251881Speter};
166251881Speter#endif
167251881Speter
168251881Speter/*
169251881Speter * MPSAFE
170251881Speter */
171251881Speter/* ARGSUSED */
172251881Speterint
173251881Speterovadvise(td, uap)
174251881Speter	struct thread *td;
175251881Speter	struct ovadvise_args *uap;
176251881Speter{
177251881Speter	/* START_GIANT_OPTIONAL */
178251881Speter	/* END_GIANT_OPTIONAL */
179251881Speter	return (EINVAL);
180251881Speter}
181251881Speter