1 /*
2 * Copyright (c) 2000-2006 Apple Computer, 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 */
58 /*
59 * File: vm/vm_kern.h
60 * Author: Avadis Tevanian, Jr., Michael Wayne Young
61 * Date: 1985
62 *
63 * Kernel memory management definitions.
64 */
65
66 #ifndef _VM_VM_KERN_H_
67 #define _VM_VM_KERN_H_
68
69 #include <mach/mach_types.h>
70 #include <mach/boolean.h>
71 #include <mach/kern_return.h>
72 #include <mach/vm_types.h>
73 #ifdef XNU_KERNEL_PRIVATE
74 #include <kern/locks.h>
75 #endif /* XNU_KERNEL_PRIVATE */
76
77
78 __BEGIN_DECLS
79
80 #ifdef KERNEL_PRIVATE
81
82 /*!
83 * @brief
84 * The VM map for the kernel.
85 *
86 * @discussion
87 * This represents the VM-managed portion of the address space.
88 *
89 * The actual address space of the kernel is larger but is managed
90 * by the pmap directly and the VM is oblivious to it. Unmanaged regions
91 * of that kind include the physical aperture or the KASAN shadow map.
92 */
93 extern vm_map_t kernel_map;
94
95
96 /*!
97 * @brief
98 * The IPC VM submap.
99 *
100 * @discussion
101 * The IPC submap is used by the Mach IPC subsystem in order to stage
102 * allocations for IPC kmsgs or to throttle debugging interfaces.
103 *
104 * This submap doesn't zero on page fault, and clients must properly
105 * erase memory or risk memory disclosures.
106 */
107 extern vm_map_t ipc_kernel_map;
108
109 #if XNU_KERNEL_PRIVATE
110
111 /*!
112 * @brief
113 * The Kext VM submap
114 *
115 * @discussion
116 * This submap is used to support unloading and paging out kexts.
117 */
118 extern vm_map_t g_kext_map __XNU_PRIVATE_EXTERN;
119
120 #else
121
122 #pragma mark - the kmem subsystem
123
124 /*!
125 * @function kmem_alloc()
126 *
127 * @brief
128 * Allocate anonymous wired memory from the kernel map or a kernel submap.
129 *
130 * @discussion
131 * The memory allocated is wired and must be deallocated with @c kmem_free()
132 * or @c mach_vm_deallocate().
133 *
134 * Kernel extensions are discouraged from using this function:
135 * consider @c IOMallocType() instead.
136 *
137 * Per kernel allocation security policies (see doc/allocators/api-basics.md),
138 * this allocation cannot be used to store pure data, @c IOMallocData()
139 * must be used instead.
140 *
141 * @param [in] map the map to allocate from, this must be the kernel map
142 * or one of its submaps.
143 * @param [out] addrp a non-NULL pointer used to return the newly allocated
144 * memory.
145 * @param [in] size the size of the memory to allocate.
146 *
147 * @returns
148 * KERN_SUCCESS the allocation succeeded,
149 * the returned address will be non-zero.
150 * KERN_INVALID_ARGUMENT
151 * the allocation failed because @c size was 0.
152 * KERN_NO_SPACE the allocation failed because the specified map
153 * is out of address space.
154 * KERN_RESOURCE_SHORTAGE
155 * the allocation failed because the kernel
156 * was out of pages and couldn't satisfy the demand.
157 */
158 extern kern_return_t kmem_alloc(
159 vm_map_t map,
160 vm_offset_t *addrp,
161 vm_size_t size);
162
163
164 /*!
165 * @function kmem_alloc_pageable()
166 *
167 * @brief
168 * Allocate anonymous pageable memory from the kernel map or a kernel submap.
169 *
170 * @discussion
171 * This call is equivalent to @c mach_vm_allocate(map, addr, size, VM_FLAGS_ANYWHERE)
172 * which should be preferred to this legacy call.
173 *
174 * The memory allocated is wired and must be deallocated with @c kmem_free()
175 * or @c mach_vm_deallocate().
176 *
177 * Per kernel allocation security policies (see doc/allocators/api-basics.md),
178 * this allocation must not be used to store kernel pointers.
179 *
180 * @param [in] map the map to allocate from, this must be the kernel map
181 * or one of its submaps.
182 * @param [out] addrp a non-NULL pointer used to return the newly allocated
183 * memory.
184 * @param [in] size the size of the memory to allocate.
185 *
186 * @returns
187 * KERN_SUCCESS the allocation succeeded,
188 * the returned address will be non-zero.
189 * KERN_NO_SPACE the allocation failed because the specified map
190 * is out of address space.
191 */
192 extern kern_return_t kmem_alloc_pageable(
193 vm_map_t map,
194 vm_offset_t *addrp,
195 vm_size_t size);
196
197
198 /*!
199 * @function kmem_alloc_kobject()
200 *
201 * @brief
202 * Allocate kobject wired memory from the kernel map or a kernel submap.
203 *
204 * @discussion
205 * The memory allocated is wired and must be deallocated with @c kmem_free()
206 * or @c mach_vm_deallocate().
207 *
208 * Memory allocated by this function is added to the VM kernel object rather
209 * than a new VM object. This makes it possible to avoid the cost of that extra
210 * VM object, but forgoes any advanced VM features such as unwiring memory, or
211 * sharing it (whether it be to an IOMMU or another address space).
212 *
213 * Kernel extensions are discouraged from using this function:
214 * consider @c IOMallocType() instead.
215 *
216 * Per kernel allocation security policies (see doc/allocators/api-basics.md),
217 * this allocation cannot be used to store pure data, @c IOMallocData()
218 * must be used instead.
219 *
220 * @param [in] map the map to allocate from, this must be the kernel map
221 * or one of its submaps.
222 * @param [out] addrp a non-NULL pointer used to return the newly allocated
223 * memory.
224 * @param [in] size the size of the memory to allocate.
225 *
226 * @returns
227 * KERN_SUCCESS the allocation succeeded,
228 * the returned address will be non-zero.
229 * KERN_INVALID_ARGUMENT
230 * the allocation failed because @c size was 0.
231 * KERN_NO_SPACE the allocation failed because the specified map
232 * is out of address space.
233 * KERN_RESOURCE_SHORTAGE
234 * the allocation failed because the kernel
235 * was out of pages and couldn't satisfy the demand.
236 */
237 extern kern_return_t kmem_alloc_kobject(
238 vm_map_t map,
239 vm_offset_t *addrp,
240 vm_size_t size);
241
242 /*!
243 * @function kmem_free()
244 *
245 * @brief
246 * Deallocates a range of memory.
247 *
248 * @discussion
249 * This call is roughly equivalent to @c mach_vm_deallocate(map, addr, size).
250 *
251 * It is possible to deallocate an allocation in several steps provided that
252 * the deallocations form a partition of the range allocated with one of
253 * the functions from the @c kmem_alloc*() family.
254 *
255 * Unlike @c mach_vm_deallocate(), this function will panic for invalid
256 * arguments, in particular for invalid sizes or a @c map argument
257 * not matching the one used for allocating.
258 *
259 * @param map the map to allocate from, this must be the kernel map
260 * or one of its submaps.
261 * @param addr the address to deallocate.
262 * @param size the size of the address to deallocate.
263 */
264 extern void kmem_free(
265 vm_map_t map,
266 vm_offset_t addr,
267 vm_size_t size);
268
269 #endif /* !XNU_KERNEL_PRIVATE */
270 #endif /* KERNEL_PRIVATE */
271
272 #pragma mark - kernel address obfuscation / hashing for logging
273
274 /*!
275 * @function vm_kernel_addrhide()
276 *
277 * @brief
278 * Unslides a kernel pointer.
279 *
280 * @discussion
281 * This is exporting the VM_KERNEL_ADDRHIDE() functionality to kernel
282 * extensions.
283 *
284 * @param addr the kernel address to unslide
285 * @param hide_addr the unslid value of @c addr if it was part of a slid
286 * region of the kernel.
287 *
288 * 0 on release kernels if @c addr is not part of a slid
289 * region of the kernel.
290 *
291 * @c addr on development kernels if @c addr is not part of
292 * a slid region of the kernel.
293 */
294 extern void vm_kernel_addrhide(
295 vm_offset_t addr,
296 vm_offset_t *hide_addr);
297
298
299 /*!
300 * @function vm_kernel_addrperm_external()
301 *
302 * @brief
303 * Unslides or "permutate" a kernel pointer.
304 *
305 * @discussion
306 * This is exporting the VM_KERNEL_ADDRPERM() functionality to kernel
307 * extensions.
308 *
309 * The level of "hiding" of heap kernel pointers done by this function is
310 * insufficient. Using @c vm_kernel_addrhash() is preferred when possible.
311 *
312 * Note that this function might cause lazy allocation to preserve the floating
313 * point register state on Intel and is generally unsafe to call under lock.
314 *
315 * @param addr the kernel address to unslide
316 * @param perm_addr the unslid value of @c addr if it was part of a slid
317 * region of the kernel.
318 */
319 extern void vm_kernel_addrperm_external(
320 vm_offset_t addr,
321 vm_offset_t *perm_addr);
322
323
324 /*!
325 * @function vm_kernel_unslide_or_perm_external()
326 *
327 * @brief
328 * Equivalent to vm_kernel_addrperm_external().
329 */
330 extern void vm_kernel_unslide_or_perm_external(
331 vm_offset_t addr,
332 vm_offset_t *perm_addr);
333
334 #if !XNU_KERNEL_PRIVATE
335
336 /*!
337 * @function vm_kernel_addrhash()
338 *
339 * @brief
340 * Unslides or hashes a kernel pointer.
341 *
342 * @discussion
343 * This is exporting the VM_KERNEL_ADDRHASH() functionality to kernel
344 * extensions.
345 *
346 * @param addr the kernel address to unslide
347 * @returns the unslid value of @c addr if it was part of a slid
348 * region of the kernel.
349 *
350 * a hashed value of @c addr otherwise.
351 */
352 extern vm_offset_t vm_kernel_addrhash(
353 vm_offset_t addr);
354
355 #else /* XNU_KERNEL_PRIVATE */
356 #pragma GCC visibility push(hidden)
357
358 /*!
359 * @brief
360 * The quantity @c vm_kernel_addrhide() uses to slide heap pointers.
361 */
362 extern vm_offset_t vm_kernel_addrperm_ext;
363
364
365 /*!
366 * @brief
367 * The quantity @c vm_kernel_addrhash() uses to hash heap pointers inside XNU.
368 */
369 extern uint64_t vm_kernel_addrhash_salt;
370
371
372 /*!
373 * @brief
374 * The quantity @c vm_kernel_addrhash() uses to hash heap pointers for kernel
375 * extensions.
376 */
377 extern uint64_t vm_kernel_addrhash_salt_ext;
378
379
380 /*!
381 * @function vm_kernel_addrhash_internal()
382 *
383 * @brief
384 * Internal function used to implement the @c vm_kernel_addrhash*() functions.
385 */
386 extern vm_offset_t vm_kernel_addrhash_internal(
387 vm_offset_t addr,
388 uint64_t salt);
389
390
391 /*!
392 * @function vm_kernel_addrhash()
393 *
394 * @brief
395 * Unslides or hashes a kernel pointer.
396 *
397 * @discussion
398 * This is exporting the VM_KERNEL_ADDRHASH() functionality to kernel
399 * extensions.
400 *
401 * @param addr the kernel address to unslide
402 * @returns the unslid value of @c addr if it was part of a slid
403 * region of the kernel.
404 *
405 * a hashed value of @c addr otherwise.
406 */
407 static inline vm_offset_t
vm_kernel_addrhash(vm_offset_t addr)408 vm_kernel_addrhash(vm_offset_t addr)
409 {
410 return vm_kernel_addrhash_internal(addr, vm_kernel_addrhash_salt);
411 }
412
413 #pragma GCC visibility pop
414 #endif /* XNU_KERNEL_PRIVATE */
415 #ifdef KERNEL_PRIVATE
416
417 #pragma mark - kern allocation names
418
419 /*!
420 * @typedef kern_allocation_name_t
421 *
422 * @brief
423 * This type is used to perform different kinds of accounting
424 * in the Mach VM subsystem.
425 */
426 #ifdef XNU_KERNEL_PRIVATE
427 typedef struct vm_allocation_site kern_allocation_name;
428 typedef kern_allocation_name *kern_allocation_name_t;
429 #else
430 typedef struct kern_allocation_name *kern_allocation_name_t;
431 #endif
432
433
434 /*!
435 * @brief
436 * Allocate a kernel allocation accounting structure.
437 *
438 * @param name a symbolic name for this accounting group.
439 * @param suballocs how many subtotals will be used for accounting.
440 * see @c kern_allocation_update_subtotal().
441 * @returns the new allocated accounting structure,
442 * this function never fails.
443 */
444 extern kern_allocation_name_t kern_allocation_name_allocate(
445 const char *name,
446 uint16_t suballocs);
447
448 /*!
449 * @brief
450 * Frees a kernel allocation accounting structure.
451 *
452 * @param allocation a structure made with @c kern_allocation_name_allocate().
453 */
454 extern void kern_allocation_name_release(
455 kern_allocation_name_t allocation);
456
457
458 /*!
459 * @brief
460 * Returns the name associated with an allocation accounting structure.
461 *
462 * @returns the name associated with that accounting structure,
463 * when made with @c kern_allocation_name_allocate().
464 */
465 extern const char *kern_allocation_get_name(
466 kern_allocation_name_t allocation);
467
468 #endif /* KERNEL_PRIVATE */
469
470 __END_DECLS
471
472 #endif /* _VM_VM_KERN_H_ */
473