1 /*
2 * Copyright (c) 2021 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * @OSF_COPYRIGHT@
30 */
31 /*
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
35 *
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
41 *
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 * Software Distribution Coordinator or [email protected]
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56
57 #ifndef _VM_VM_MAP_INTERNAL_H_
58 #define _VM_VM_MAP_INTERNAL_H_
59
60 #include <vm/vm_map.h>
61 #include <vm/vm_kern.h>
62
63 __BEGIN_DECLS
64 #pragma GCC visibility push(hidden)
65
66 /*
67 * This file contains interfaces that are private to the VM
68 */
69
70 #define KiB(x) (1024 * (x))
71 #define MeB(x) (1024 * 1024 * (x))
72
73 #if __LP64__
74 #define KMEM_SMALLMAP_THRESHOLD (MeB(1))
75 #else
76 #define KMEM_SMALLMAP_THRESHOLD (KiB(256))
77 #endif
78
79 #if CONFIG_MAP_RANGES
80 /*
81 * This has been tuned for iOS only
82 */
83 #define VM_MAP_USER_RANGE_MAX (GiB(12))
84 #endif
85
86 struct kmem_page_meta;
87
88 /* Initialize the module */
89 extern void vm_map_init(void);
90
91 extern kern_return_t vm_map_locate_space(
92 vm_map_t map,
93 vm_map_size_t size,
94 vm_map_offset_t mask,
95 vm_map_kernel_flags_t vmk_flags,
96 vm_map_offset_t *start_inout,
97 vm_map_entry_t *entry_out);
98
99 /* Allocate a range in the specified virtual address map and
100 * return the entry allocated for that range. */
101 extern kern_return_t vm_map_find_space(
102 vm_map_t map,
103 vm_map_address_t hint_addr,
104 vm_map_size_t size,
105 vm_map_offset_t mask,
106 vm_map_kernel_flags_t vmk_flags,
107 vm_map_entry_t *o_entry); /* OUT */
108
109 extern void vm_map_clip_start(
110 vm_map_t map,
111 vm_map_entry_t entry,
112 vm_map_offset_t endaddr);
113
114 extern void vm_map_clip_end(
115 vm_map_t map,
116 vm_map_entry_t entry,
117 vm_map_offset_t endaddr);
118
119 extern boolean_t vm_map_entry_should_cow_for_true_share(
120 vm_map_entry_t entry);
121
122 /*!
123 * @typedef vmr_flags_t
124 *
125 * @brief
126 * Flags for vm_map_remove() and vm_map_delete()
127 *
128 * @const VM_MAP_REMOVE_NO_FLAGS
129 * When no special flags is to be passed.
130 *
131 * @const VM_MAP_REMOVE_KUNWIRE
132 * Unwire memory as a side effect.
133 *
134 * @const VM_MAP_REMOVE_INTERRUPTIBLE
135 * Whether the call is interruptible if it needs to wait for a vm map
136 * entry to quiesce (interruption leads to KERN_ABORTED).
137 *
138 * @const VM_MAP_REMOVE_NOKUNWIRE_LAST
139 * Do not unwire the last page of this entry during remove.
140 * (Used by kmem_realloc()).
141 *
142 * @const VM_MAP_REMOVE_IMMUTABLE
143 * Allow permanent entries to be removed.
144 *
145 * @const VM_MAP_REMOVE_GAPS_FAIL
146 * Return KERN_INVALID_VALUE when a gap is being removed instead of panicking.
147 *
148 * @const VM_MAP_REMOVE_NO_YIELD.
149 * Try to avoid yielding during this call.
150 *
151 * @const VM_MAP_REMOVE_GUESS_SIZE
152 * The caller doesn't know the precise size of the entry,
153 * but the address must match an atomic entry.
154 *
155 * @const VM_MAP_REMOVE_IMMUTABLE_CODE
156 * Allow executables entries to be removed (for VM_PROT_COPY),
157 * which is used by debuggers.
158 */
159 __options_decl(vmr_flags_t, uint32_t, {
160 VM_MAP_REMOVE_NO_FLAGS = 0x000,
161 VM_MAP_REMOVE_KUNWIRE = 0x001,
162 VM_MAP_REMOVE_INTERRUPTIBLE = 0x002,
163 VM_MAP_REMOVE_NOKUNWIRE_LAST = 0x004,
164 VM_MAP_REMOVE_NO_MAP_ALIGN = 0x008,
165 VM_MAP_REMOVE_IMMUTABLE = 0x010,
166 VM_MAP_REMOVE_GAPS_FAIL = 0x020,
167 VM_MAP_REMOVE_NO_YIELD = 0x040,
168 VM_MAP_REMOVE_GUESS_SIZE = 0x080,
169 VM_MAP_REMOVE_IMMUTABLE_CODE = 0x100,
170 });
171
172 /* Deallocate a region */
173 extern kmem_return_t vm_map_remove_guard(
174 vm_map_t map,
175 vm_map_offset_t start,
176 vm_map_offset_t end,
177 vmr_flags_t flags,
178 kmem_guard_t guard) __result_use_check;
179
180 extern kmem_return_t vm_map_remove_and_unlock(
181 vm_map_t map,
182 vm_map_offset_t start,
183 vm_map_offset_t end,
184 vmr_flags_t flags,
185 kmem_guard_t guard) __result_use_check;
186
187 /* Deallocate a region */
188 static inline void
vm_map_remove(vm_map_t map,vm_map_offset_t start,vm_map_offset_t end)189 vm_map_remove(
190 vm_map_t map,
191 vm_map_offset_t start,
192 vm_map_offset_t end)
193 {
194 vmr_flags_t flags = VM_MAP_REMOVE_NO_FLAGS;
195 kmem_guard_t guard = KMEM_GUARD_NONE;
196
197 (void)vm_map_remove_guard(map, start, end, flags, guard);
198 }
199
200 extern bool kmem_is_ptr_range(vm_map_range_id_t range_id);
201
202 extern mach_vm_range_t kmem_validate_range_for_overwrite(
203 vm_map_offset_t addr,
204 vm_map_size_t size);
205
206 extern uint32_t kmem_addr_get_slot_idx(
207 vm_map_offset_t start,
208 vm_map_offset_t end,
209 vm_map_range_id_t range_id,
210 struct kmem_page_meta **meta,
211 uint32_t *size_idx,
212 mach_vm_range_t slot);
213
214 extern void kmem_validate_slot(
215 vm_map_offset_t addr,
216 struct kmem_page_meta *meta,
217 uint32_t size_idx,
218 uint32_t slot_idx);
219
220 /*
221 * Function used to allocate VA from kmem pointer ranges
222 */
223 extern kern_return_t kmem_locate_space(
224 vm_map_size_t size,
225 vm_map_range_id_t range_id,
226 bool direction,
227 vm_map_offset_t *start_inout,
228 vm_map_entry_t *entry_out);
229
230 /*
231 * Function used to free VA to kmem pointer ranges
232 */
233 extern void kmem_free_space(
234 vm_map_offset_t start,
235 vm_map_offset_t end,
236 vm_map_range_id_t range_id,
237 mach_vm_range_t slot);
238
239 #pragma GCC visibility pop
240 __END_DECLS
241
242 #endif /* _VM_VM_MAP_INTERNAL_H_ */
243