1 /*	$OpenBSD: uvm_map_i.h,v 1.16 2002/10/29 18:30:21 art Exp $	*/
2 /*	$NetBSD: uvm_map_i.h,v 1.18 2000/11/27 08:40:04 chs Exp $	*/
3 
4 /*
5  * Copyright (c) 1997 Charles D. Cranor and Washington University.
6  * Copyright (c) 1991, 1993, The Regents of the University of California.
7  *
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * The Mach Operating System project at Carnegie-Mellon University.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *	This product includes software developed by Charles D. Cranor,
24  *      Washington University, the University of California, Berkeley and
25  *      its contributors.
26  * 4. Neither the name of the University nor the names of its contributors
27  *    may be used to endorse or promote products derived from this software
28  *    without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40  * SUCH DAMAGE.
41  *
42  *	@(#)vm_map.c    8.3 (Berkeley) 1/12/94
43  * from: Id: uvm_map_i.h,v 1.1.2.1 1997/08/14 19:10:50 chuck Exp
44  *
45  *
46  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
47  * All rights reserved.
48  *
49  * Permission to use, copy, modify and distribute this software and
50  * its documentation is hereby granted, provided that both the copyright
51  * notice and this permission notice appear in all copies of the
52  * software, derivative works or modified versions, and any portions
53  * thereof, and that both notices appear in supporting documentation.
54  *
55  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
56  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
57  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
58  *
59  * Carnegie Mellon requests users of this software to return to
60  *
61  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
62  *  School of Computer Science
63  *  Carnegie Mellon University
64  *  Pittsburgh PA 15213-3890
65  *
66  * any improvements or extensions that they make and grant Carnegie the
67  * rights to redistribute these changes.
68  */
69 
70 #ifndef _UVM_UVM_MAP_I_H_
71 #define _UVM_UVM_MAP_I_H_
72 
73 /*
74  * uvm_map_i.h
75  */
76 
77 /*
78  * inline functions [maybe]
79  */
80 
81 #if defined(UVM_MAP_INLINE) || defined(UVM_MAP)
82 
83 /*
84  * uvm_map_create: create map
85  */
86 
87 MAP_INLINE vm_map_t
uvm_map_create(pmap,min,max,flags)88 uvm_map_create(pmap, min, max, flags)
89 	pmap_t pmap;
90 	vaddr_t min, max;
91 	int flags;
92 {
93 	vm_map_t result;
94 
95 	MALLOC(result, vm_map_t,
96 	    (flags & VM_MAP_INTRSAFE) ? sizeof(struct vm_map_intrsafe) :
97 					sizeof(struct vm_map),
98 	    M_VMMAP, M_WAITOK);
99 	uvm_map_setup(result, min, max, flags);
100 	result->pmap = pmap;
101 	return(result);
102 }
103 
104 /*
105  * uvm_map_setup: init map
106  *
107  * => map must not be in service yet.
108  */
109 
110 MAP_INLINE void
uvm_map_setup(map,min,max,flags)111 uvm_map_setup(map, min, max, flags)
112 	vm_map_t map;
113 	vaddr_t min, max;
114 	int flags;
115 {
116 
117 	RB_INIT(&map->rbhead);
118 	map->header.next = map->header.prev = &map->header;
119 	map->nentries = 0;
120 	map->size = 0;
121 	map->ref_count = 1;
122 	map->min_offset = min;
123 	map->max_offset = max;
124 	map->flags = flags;
125 	map->first_free = &map->header;
126 	map->hint = &map->header;
127 	map->timestamp = 0;
128 	lockinit(&map->lock, PVM, "vmmaplk", 0, 0);
129 	simple_lock_init(&map->ref_lock);
130 	simple_lock_init(&map->hint_lock);
131 	simple_lock_init(&map->flags_lock);
132 
133 	/*
134 	 * If the map is interrupt safe, place it on the list
135 	 * of interrupt safe maps, for uvm_fault().
136 	 *
137 	 * We almost never set up an interrupt-safe map, but we set
138 	 * up quite a few regular ones (at every fork!), so put
139 	 * interrupt-safe map setup in the slow path.
140 	 */
141 	if (__predict_false(flags & VM_MAP_INTRSAFE)) {
142 		struct vm_map_intrsafe *vmi = (struct vm_map_intrsafe *)map;
143 		int s;
144 
145 		s = vmi_list_lock();
146 		LIST_INSERT_HEAD(&vmi_list, vmi, vmi_list);
147 		vmi_list_unlock(s);
148 	}
149 }
150 
151 
152 /*
153  *   U N M A P   -   m a i n   e n t r y   p o i n t
154  */
155 
156 /*
157  * uvm_unmap: remove mappings from a vm_map (from "start" up to "stop")
158  *
159  * => caller must check alignment and size
160  * => map must be unlocked (we will lock it)
161  */
162 
163 MAP_INLINE void
uvm_unmap(map,start,end)164 uvm_unmap(map, start, end)
165 	vm_map_t map;
166 	vaddr_t start,end;
167 {
168 	vm_map_entry_t dead_entries;
169 	UVMHIST_FUNC("uvm_unmap"); UVMHIST_CALLED(maphist);
170 
171 	UVMHIST_LOG(maphist, "  (map=0x%x, start=0x%x, end=0x%x)",
172 	    map, start, end, 0);
173 	/*
174 	 * work now done by helper functions.   wipe the pmap's and then
175 	 * detach from the dead entries...
176 	 */
177 	vm_map_lock(map);
178 	uvm_unmap_remove(map, start, end, &dead_entries);
179 	vm_map_unlock(map);
180 
181 	if (dead_entries != NULL)
182 		uvm_unmap_detach(dead_entries, 0);
183 
184 	UVMHIST_LOG(maphist, "<- done", 0,0,0,0);
185 }
186 
187 
188 /*
189  * uvm_map_reference: add reference to a map
190  *
191  * => map need not be locked (we use ref_lock).
192  */
193 
194 MAP_INLINE void
uvm_map_reference(map)195 uvm_map_reference(map)
196 	vm_map_t map;
197 {
198 	simple_lock(&map->ref_lock);
199 	map->ref_count++;
200 	simple_unlock(&map->ref_lock);
201 }
202 
203 /*
204  * uvm_map_deallocate: drop reference to a map
205  *
206  * => caller must not lock map
207  * => we will zap map if ref count goes to zero
208  */
209 
210 MAP_INLINE void
uvm_map_deallocate(map)211 uvm_map_deallocate(map)
212 	vm_map_t map;
213 {
214 	int c;
215 
216 	simple_lock(&map->ref_lock);
217 	c = --map->ref_count;
218 	simple_unlock(&map->ref_lock);
219 	if (c > 0) {
220 		return;
221 	}
222 
223 	/*
224 	 * all references gone.   unmap and free.
225 	 */
226 
227 	uvm_unmap(map, map->min_offset, map->max_offset);
228 	pmap_destroy(map->pmap);
229 	FREE(map, M_VMMAP);
230 }
231 
232 #endif /* defined(UVM_MAP_INLINE) || defined(UVM_MAP) */
233 
234 #endif /* _UVM_UVM_MAP_I_H_ */
235