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 Software.Distribution@CS.CMU.EDU
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
79struct kmem_page_meta;
80
81
82/* We can't extern this from vm_kern.h because we can't include pmap.h */
83extern void kernel_memory_populate_object_and_unlock(
84 vm_object_t object, /* must be locked */
85 vm_address_t addr,
86 vm_offset_t offset,
87 vm_size_t size,
88 struct vm_page *page_list,
89 kma_flags_t flags,
90 vm_tag_t tag,
91 vm_prot_t prot,
92 pmap_mapping_type_t mapping_type);
93
94/* Initialize the module */
95extern void vm_map_init(void);
96
97extern kern_return_t vm_map_locate_space(
98 vm_map_t map,
99 vm_map_size_t size,
100 vm_map_offset_t mask,
101 vm_map_kernel_flags_t vmk_flags,
102 vm_map_offset_t *start_inout,
103 vm_map_entry_t *entry_out);
104
105/* Allocate a range in the specified virtual address map and
106 * return the entry allocated for that range. */
107extern kern_return_t vm_map_find_space(
108 vm_map_t map,
109 vm_map_address_t hint_addr,
110 vm_map_size_t size,
111 vm_map_offset_t mask,
112 vm_map_kernel_flags_t vmk_flags,
113 vm_map_entry_t *o_entry); /* OUT */
114
115extern void vm_map_clip_start(
116 vm_map_t map,
117 vm_map_entry_t entry,
118 vm_map_offset_t endaddr);
119
120extern void vm_map_clip_end(
121 vm_map_t map,
122 vm_map_entry_t entry,
123 vm_map_offset_t endaddr);
124
125extern boolean_t vm_map_entry_should_cow_for_true_share(
126 vm_map_entry_t entry);
127
128/*!
129 * @typedef vmr_flags_t
130 *
131 * @brief
132 * Flags for vm_map_remove() and vm_map_delete()
133 *
134 * @const VM_MAP_REMOVE_NO_FLAGS
135 * When no special flags is to be passed.
136 *
137 * @const VM_MAP_REMOVE_KUNWIRE
138 * Unwire memory as a side effect.
139 *
140 * @const VM_MAP_REMOVE_INTERRUPTIBLE
141 * Whether the call is interruptible if it needs to wait for a vm map
142 * entry to quiesce (interruption leads to KERN_ABORTED).
143 *
144 * @const VM_MAP_REMOVE_NOKUNWIRE_LAST
145 * Do not unwire the last page of this entry during remove.
146 * (Used by kmem_realloc()).
147 *
148 * @const VM_MAP_REMOVE_IMMUTABLE
149 * Allow permanent entries to be removed.
150 *
151 * @const VM_MAP_REMOVE_GAPS_FAIL
152 * Return KERN_INVALID_VALUE when a gap is being removed instead of panicking.
153 *
154 * @const VM_MAP_REMOVE_NO_YIELD.
155 * Try to avoid yielding during this call.
156 *
157 * @const VM_MAP_REMOVE_GUESS_SIZE
158 * The caller doesn't know the precise size of the entry,
159 * but the address must match an atomic entry.
160 *
161 * @const VM_MAP_REMOVE_IMMUTABLE_CODE
162 * Allow executables entries to be removed (for VM_PROT_COPY),
163 * which is used by debuggers.
164 */
165__options_decl(vmr_flags_t, uint32_t, {
166 VM_MAP_REMOVE_NO_FLAGS = 0x000,
167 VM_MAP_REMOVE_KUNWIRE = 0x001,
168 VM_MAP_REMOVE_INTERRUPTIBLE = 0x002,
169 VM_MAP_REMOVE_NOKUNWIRE_LAST = 0x004,
170 VM_MAP_REMOVE_NO_MAP_ALIGN = 0x008,
171 VM_MAP_REMOVE_IMMUTABLE = 0x010,
172 VM_MAP_REMOVE_GAPS_FAIL = 0x020,
173 VM_MAP_REMOVE_NO_YIELD = 0x040,
174 VM_MAP_REMOVE_GUESS_SIZE = 0x080,
175 VM_MAP_REMOVE_IMMUTABLE_CODE = 0x100,
176 VM_MAP_REMOVE_TO_OVERWRITE = 0x200,
177});
178
179/* Deallocate a region */
180extern kmem_return_t vm_map_remove_guard(
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
187extern kmem_return_t vm_map_remove_and_unlock(
188 vm_map_t map,
189 vm_map_offset_t start,
190 vm_map_offset_t end,
191 vmr_flags_t flags,
192 kmem_guard_t guard) __result_use_check;
193
194/* Deallocate a region */
195static inline void
196vm_map_remove(
197 vm_map_t map,
198 vm_map_offset_t start,
199 vm_map_offset_t end)
200{
201 vmr_flags_t flags = VM_MAP_REMOVE_NO_FLAGS;
202 kmem_guard_t guard = KMEM_GUARD_NONE;
203
204 (void)vm_map_remove_guard(map, start, end, flags, guard);
205}
206
207extern bool kmem_is_ptr_range(vm_map_range_id_t range_id);
208
209extern mach_vm_range_t kmem_validate_range_for_overwrite(
210 vm_map_offset_t addr,
211 vm_map_size_t size);
212
213extern uint32_t kmem_addr_get_slot_idx(
214 vm_map_offset_t start,
215 vm_map_offset_t end,
216 vm_map_range_id_t range_id,
217 struct kmem_page_meta **meta,
218 uint32_t *size_idx,
219 mach_vm_range_t slot);
220
221extern void kmem_validate_slot(
222 vm_map_offset_t addr,
223 struct kmem_page_meta *meta,
224 uint32_t size_idx,
225 uint32_t slot_idx);
226
227/*
228 * Function used to allocate VA from kmem pointer ranges
229 */
230extern kern_return_t kmem_locate_space(
231 vm_map_size_t size,
232 vm_map_range_id_t range_id,
233 bool direction,
234 vm_map_offset_t *start_inout,
235 vm_map_entry_t *entry_out);
236
237/*
238 * Function used to free VA to kmem pointer ranges
239 */
240extern void kmem_free_space(
241 vm_map_offset_t start,
242 vm_map_offset_t end,
243 vm_map_range_id_t range_id,
244 mach_vm_range_t slot);
245
246#pragma GCC visibility pop
247__END_DECLS
248
249#endif /* _VM_VM_MAP_INTERNAL_H_ */
250