xref: /xnu-8020.121.3/osfmk/kern/restartable.h (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
1 /*
2  * Copyright (c) 2019 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 #ifndef _KERN_RESTARTABLE_H_
30 #define _KERN_RESTARTABLE_H_
31 
32 #include <sys/cdefs.h>
33 #include <mach/message.h>
34 #include <mach/task.h>
35 
36 __BEGIN_DECLS
37 
38 /*!
39  * @typedef task_restartable_range_t
40  *
41  * @brief
42  * Describes a userspace recoverable range.
43  *
44  * @field location
45  * The pointer to the beginning of a restartable section.
46  *
47  * @field length
48  * The length of the critical section anchored at location.
49  *
50  * @field recovery_offs
51  * The offset from the initial location that should be used for the recovery
52  * codepath.
53  *
54  * @field flags
55  * Currently unused, pass 0.
56  */
57 typedef struct {
58 	mach_vm_address_t location;
59 	unsigned short    length;
60 	unsigned short    recovery_offs;
61 	unsigned int      flags;
62 } task_restartable_range_t;
63 
64 typedef task_restartable_range_t *task_restartable_range_array_t;
65 
66 /*!
67  * @function task_restartable_ranges_register
68  *
69  * @brief
70  * Register a set of restartable ranges for the current task.
71  *
72  * @param task
73  * The task to operate on
74  *
75  * @param ranges
76  * An array of address ranges for which PC resets are performed.
77  *
78  * @param count
79  * The number of address ranges.
80  *
81  * @returns
82  * - KERN_SUCCESS on success
83  * - KERN_FAILURE if the task isn't the current one
84  * - KERN_INVALID_ARGUMENT for various invalid inputs
85  * - KERN_NOT_SUPPORTED the request is not supported (second registration on
86  *   release kernels, registration when the task has gone wide)
87  * - KERN_RESOURCE_SHORTAGE if not enough memory
88  */
89 extern kern_return_t task_restartable_ranges_register(
90 	task_t                         task,
91 	task_restartable_range_array_t ranges,
92 	mach_msg_type_number_t         count);
93 
94 /*!
95  * @function task_restartable_ranges_synchronize
96  *
97  * @brief
98  * Require for all threads in the task to reset their PC
99  * if within a restartable range.
100  *
101  * @param task
102  * The task to operate on (needs to be current task)
103  *
104  * @returns
105  * - KERN_SUCCESS
106  * - KERN_FAILURE if the task isn't the current one
107  */
108 extern kern_return_t task_restartable_ranges_synchronize(task_t task);
109 
110 /*!
111  * @const TASK_RESTARTABLE_OFFSET_MAX
112  * The maximum value length / recovery_offs can have.
113  */
114 #define TASK_RESTARTABLE_OFFSET_MAX  4096u
115 
116 #ifdef KERNEL_PRIVATE
117 
118 struct restartable_ranges;
119 
120 /**
121  * @function restartable_init
122  *
123  * @brief
124  * Initializes the restartable module.
125  */
126 extern void restartable_init(void);
127 
128 /**
129  * @function restartable_ranges_release
130  *
131  * @brief
132  * Release a reference on a restartable range.
133  */
134 extern void restartable_ranges_release(struct restartable_ranges *ranges);
135 
136 /**
137  * @function thread_reset_pcs_ast
138  *
139  * @brief
140  * Perform the work at the AST boundary to reset thread PCS.
141  */
142 extern void thread_reset_pcs_ast(task_t task, struct thread *thread);
143 
144 #endif // KERNEL_PRIVATE
145 
146 __END_DECLS
147 
148 #endif  /* _KERN_RESTARTABLE_H_ */
149