xref: /xnu-12377.81.4/tests/vm/configurator/vm_configurator_helpers.h (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 2024 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 /*
30  * vm_configurator_helpers.h
31  *
32  * Assorted functions used by multiple vm_configurator tests.
33  */
34 
35 #ifndef VM_CONFIGURATOR_HELPERS_H
36 #define VM_CONFIGURATOR_HELPERS_H
37 
38 #include "vm_configurator.h"
39 
40 /*
41  * Clear some bits from EXC_GUARD behavior, then set some bits.
42  * Halt with T_FAIL if task_get/set_exc_guard_behavior() fails.
43  */
44 static inline void
clear_then_set_exc_guard_behavior(task_exc_guard_behavior_t clear,task_exc_guard_behavior_t set)45 clear_then_set_exc_guard_behavior(
46 	task_exc_guard_behavior_t clear,
47 	task_exc_guard_behavior_t set)
48 {
49 	task_exc_guard_behavior_t behavior;
50 	kern_return_t kr = task_get_exc_guard_behavior(mach_task_self(), &behavior);
51 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "get EXC_GUARD behavior");
52 
53 	behavior &= ~clear;
54 	behavior |= set;
55 
56 	kr = task_set_exc_guard_behavior(mach_task_self(), behavior);
57 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "update EXC_GUARD behavior");
58 }
59 
60 /*
61  * Disable VM EXC_GUARD exceptions.
62  * Halt with T_FAIL if they cannot be disabled.
63  */
64 static inline void
disable_vm_exc_guard(void)65 disable_vm_exc_guard(void)
66 {
67 	clear_then_set_exc_guard_behavior(
68 		TASK_EXC_GUARD_VM_ALL,  /* clear */
69 		0 /* set */);
70 }
71 
72 /*
73  * Enable VM EXC_GUARD fatal exceptions.
74  * Halt with T_FAIL if they cannot be enabled.
75  */
76 static inline void
enable_fatal_vm_exc_guard(void)77 enable_fatal_vm_exc_guard(void)
78 {
79 	clear_then_set_exc_guard_behavior(
80 		TASK_EXC_GUARD_VM_ALL,  /* clear */
81 		TASK_EXC_GUARD_VM_DELIVER | TASK_EXC_GUARD_VM_FATAL /* set */);
82 }
83 
84 /*
85  * Enable VM EXC_GUARD non-fatal exceptions.
86  * Halt with T_FAIL if they cannot be enabled.
87  */
88 static inline void
enable_non_fatal_vm_exc_guard(void)89 enable_non_fatal_vm_exc_guard(void)
90 {
91 	clear_then_set_exc_guard_behavior(
92 		TASK_EXC_GUARD_VM_ALL,  /* clear */
93 		TASK_EXC_GUARD_VM_DELIVER /* set */);
94 }
95 
96 /*
97  * Update the checker list after a successful call to vm_deallocate()
98  * of any number of ordinary allocations and holes.
99  * Don't use this if anything may be permanent entries.
100  */
101 static inline void
checker_perform_successful_vm_deallocate(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)102 checker_perform_successful_vm_deallocate(
103 	checker_list_t *checker_list,
104 	mach_vm_address_t start,
105 	mach_vm_size_t size)
106 {
107 	/* this may create adjacent hole checkers, but we don't care */
108 	entry_checker_range_t limit =
109 	    checker_list_find_and_clip_including_holes(checker_list, start, size);
110 	checker_list_free_range(checker_list, limit);
111 }
112 
113 /*
114  * Update the checker list after a successful call to vm_allocate()
115  * of a permanent entry, which makes the memory inaccessible.
116  * On entry, the range must be a single checker for a permanent allocation.
117  */
118 static inline void
checker_perform_vm_deallocate_permanent(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)119 checker_perform_vm_deallocate_permanent(
120 	checker_list_t *checker_list,
121 	mach_vm_address_t start,
122 	mach_vm_size_t size)
123 {
124 	/* Find the checker and verify its address range and permanence. */
125 	vm_entry_checker_t *checker =
126 	    checker_list_find_allocation(checker_list, start);
127 	assert(checker);
128 	assert(checker->address == start);
129 	assert(checker->size == size);
130 	assert(checker->permanent == true);
131 
132 	/* Mark the memory as inaccessible. */
133 	checker->protection = VM_PROT_NONE;
134 	checker->max_protection = VM_PROT_NONE;
135 }
136 
137 #endif  /* VM_CONFIGURATOR_HELPERS_H */
138