]> git.saurik.com Git - apple/xnu.git/blame - osfmk/vm/vm_shared_region.h
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / osfmk / vm / vm_shared_region.h
CommitLineData
2d21ac55
A
1/*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
0a7de745 5 *
2d21ac55
A
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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
0a7de745 12 *
2d21ac55
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
0a7de745 20 *
2d21ac55
A
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 *
25 * File: vm/vm_shared_region.h
26 *
0a7de745 27 * protos and struct definitions for shared region
2d21ac55
A
28 */
29
30#ifndef _VM_SHARED_REGION_H_
31#define _VM_SHARED_REGION_H_
32
0a7de745 33#ifdef KERNEL_PRIVATE
2d21ac55
A
34
35#include <mach/vm_prot.h>
36#include <mach/mach_types.h>
37#include <mach/shared_region.h>
38
39#include <kern/kern_types.h>
40#include <kern/macro_help.h>
41
42#include <vm/vm_map.h>
43
44extern int shared_region_version;
45extern int shared_region_persistence;
46
47#if DEBUG
48extern int shared_region_debug;
0a7de745
A
49#define SHARED_REGION_DEBUG(args) \
50 MACRO_BEGIN \
51 if (shared_region_debug) { \
52 kprintf args; \
53 } \
2d21ac55
A
54 MACRO_END
55#else /* DEBUG */
56#define SHARED_REGION_DEBUG(args)
57#endif /* DEBUG */
58
59extern int shared_region_trace_level;
d9a64523
A
60
61extern struct vm_shared_region *init_task_shared_region;
62
0a7de745
A
63#define SHARED_REGION_TRACE_NONE_LVL 0 /* no trace */
64#define SHARED_REGION_TRACE_ERROR_LVL 1 /* trace abnormal events */
65#define SHARED_REGION_TRACE_INFO_LVL 2 /* trace all events */
66#define SHARED_REGION_TRACE_DEBUG_LVL 3 /* extra traces for debug */
67#define SHARED_REGION_TRACE(level, args) \
68 MACRO_BEGIN \
69 if (shared_region_trace_level >= level) { \
70 printf args; \
71 } \
2d21ac55
A
72 MACRO_END
73#define SHARED_REGION_TRACE_NONE(args)
0a7de745
A
74#define SHARED_REGION_TRACE_ERROR(args) \
75 MACRO_BEGIN \
76 SHARED_REGION_TRACE(SHARED_REGION_TRACE_ERROR_LVL, \
77 args); \
2d21ac55 78 MACRO_END
0a7de745
A
79#define SHARED_REGION_TRACE_INFO(args) \
80 MACRO_BEGIN \
81 SHARED_REGION_TRACE(SHARED_REGION_TRACE_INFO_LVL, \
82 args); \
2d21ac55 83 MACRO_END
0a7de745
A
84#define SHARED_REGION_TRACE_DEBUG(args) \
85 MACRO_BEGIN \
86 SHARED_REGION_TRACE(SHARED_REGION_TRACE_DEBUG_LVL, \
87 args); \
2d21ac55
A
88 MACRO_END
89
90typedef struct vm_shared_region *vm_shared_region_t;
91
92#ifdef MACH_KERNEL_PRIVATE
93
94#include <kern/queue.h>
95#include <vm/vm_object.h>
96#include <vm/memory_object.h>
97
0a7de745 98#define PAGE_SIZE_FOR_SR_SLIDE 4096
39037602
A
99
100/* Documentation for the slide info format can be found in the dyld project in
101 * the file 'launch-cache/dyld_cache_format.h'. */
102
6d2010ae 103
39037602
A
104typedef struct vm_shared_region_slide_info_entry_v2 *vm_shared_region_slide_info_entry_v2_t;
105struct vm_shared_region_slide_info_entry_v2 {
0a7de745
A
106 uint32_t version;
107 uint32_t page_size;
108 uint32_t page_starts_offset;
109 uint32_t page_starts_count;
110 uint32_t page_extras_offset;
111 uint32_t page_extras_count;
112 uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location
113 uint64_t value_add;
39037602
A
114 // uint16_t page_starts[page_starts_count];
115 // uint16_t page_extras[page_extras_count];
116};
117
0a7de745
A
118#define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags
119#define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 0x8000 // index is into extras array (not starts array)
120#define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing
121#define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page
122#define DYLD_CACHE_SLIDE_PAGE_VALUE 0x3FFF // bitwise negation of DYLD_CACHE_SLIDE_PAGE_ATTRS
123#define DYLD_CACHE_SLIDE_PAGE_OFFSET_SHIFT 2
39037602 124
d9a64523 125typedef struct vm_shared_region_slide_info_entry_v3 *vm_shared_region_slide_info_entry_v3_t;
0a7de745
A
126struct vm_shared_region_slide_info_entry_v3 {
127 uint32_t version; // currently 3
128 uint32_t page_size; // currently 4096 (may also be 16384)
129 uint32_t page_starts_count;
130 uint64_t value_add;
131 uint16_t page_starts[] /* page_starts_count */;
d9a64523
A
132};
133
0a7de745 134#define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing
d9a64523
A
135
136
137typedef struct vm_shared_region_slide_info_entry_v4 *vm_shared_region_slide_info_entry_v4_t;
138struct vm_shared_region_slide_info_entry_v4 {
0a7de745
A
139 uint32_t version; // currently 4
140 uint32_t page_size; // currently 4096 (may also be 16384)
141 uint32_t page_starts_offset;
142 uint32_t page_starts_count;
143 uint32_t page_extras_offset;
144 uint32_t page_extras_count;
145 uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000)
146 uint64_t value_add; // base address of cache
147 // uint16_t page_starts[page_starts_count];
148 // uint16_t page_extras[page_extras_count];
d9a64523
A
149};
150
151#define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing
152#define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // index into starts or extras
153#define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not starts array)
154#define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page
155
156
157
39037602
A
158typedef union vm_shared_region_slide_info_entry *vm_shared_region_slide_info_entry_t;
159union vm_shared_region_slide_info_entry {
f427ee49
A
160 uint32_t version;
161 struct vm_shared_region_slide_info_entry_v2 v2;
162 struct vm_shared_region_slide_info_entry_v3 v3;
0a7de745 163 struct vm_shared_region_slide_info_entry_v4 v4;
39037602
A
164};
165
f427ee49
A
166#define MIN_SLIDE_INFO_SIZE \
167 MIN(sizeof(struct vm_shared_region_slide_info_entry_v2), \
168 MIN(sizeof(struct vm_shared_region_slide_info_entry_v3), \
169 sizeof(struct vm_shared_region_slide_info_entry_v4)))
170
171/*
172 * This is the information used by the shared cache pager for sub-sections
173 * which must be modified for relocations and/or pointer authentications
174 * before it can be used. The shared_region_pager gets source pages from
175 * the shared cache file and modifies them -- see shared_region_pager_data_request().
176 *
177 * A single pager may be used from multiple shared regions provided:
178 * - same si_slide_object, si_start, si_end, si_slide, si_ptrauth and si_jop_key
179 * - The size and contents of si_slide_info_entry are the same.
180 */
181typedef struct vm_shared_region_slide_info {
182 uint32_t si_slide; /* the distance that the file data is relocated */
183 bool si_slid;
184#if __has_feature(ptrauth_calls)
185 bool si_ptrauth;
186 uint64_t si_jop_key;
187 struct vm_shared_region *si_shared_region; /* so we can ref/dealloc for authenticated slide info */
188#endif /* __has_feature(ptrauth_calls) */
189 mach_vm_address_t si_slid_address;
190 mach_vm_offset_t si_start; /* start offset in si_slide_object */
191 mach_vm_offset_t si_end;
192 vm_object_t si_slide_object; /* The source object for the pages to be modified */
193 mach_vm_size_t si_slide_info_size; /* size of dyld provided relocation information */
194 vm_shared_region_slide_info_entry_t si_slide_info_entry; /* dyld provided relocation information */
195} *vm_shared_region_slide_info_t;
6d2010ae 196
f427ee49
A
197/*
198 * Data structure that represents a unique shared cache region.
199 */
39236c6e 200struct vm_shared_region {
0a7de745 201 uint32_t sr_ref_count;
f427ee49 202 uint32_t sr_slide;
0a7de745
A
203 queue_chain_t sr_q;
204 void *sr_root_dir;
205 cpu_type_t sr_cpu_type;
206 cpu_subtype_t sr_cpu_subtype;
0a7de745
A
207 ipc_port_t sr_mem_entry;
208 mach_vm_offset_t sr_first_mapping;
209 mach_vm_offset_t sr_base_address;
210 mach_vm_size_t sr_size;
211 mach_vm_offset_t sr_pmap_nesting_start;
212 mach_vm_size_t sr_pmap_nesting_size;
213 thread_call_t sr_timer_call;
0a7de745 214 uuid_t sr_uuid;
f427ee49
A
215
216 bool sr_mapping_in_progress;
217 bool sr_slide_in_progress;
218 bool sr_64bit;
219 bool sr_persists;
220 bool sr_uuid_copied;
221 bool sr_stale; /* This region should never be used again. */
222
223#if __has_feature(ptrauth_calls)
224 bool sr_reslide; /* Special shared region for suspected attacked processes */
225#define NUM_SR_AUTH_SECTIONS 2
226 vm_shared_region_slide_info_t sr_auth_section[NUM_SR_AUTH_SECTIONS];
227 uint_t sr_num_auth_section;
228#endif /* __has_feature(ptrauth_calls) */
229
0a7de745 230 uint32_t sr_images_count;
d9a64523 231 struct dyld_uuid_info_64 *sr_images;
39236c6e 232};
6d2010ae 233
f427ee49
A
234extern kern_return_t vm_shared_region_slide_page(
235 vm_shared_region_slide_info_t si,
236 vm_offset_t vaddr,
237 mach_vm_offset_t uservaddr,
238 uint32_t pageIndex,
239 uint64_t jop_key);
240extern uint64_t shared_region_find_key(char *shared_region_id);
2d21ac55
A
241#else /* !MACH_KERNEL_PRIVATE */
242
243struct vm_shared_region;
6d2010ae
A
244struct vm_shared_region_slide_info;
245struct vm_shared_region_slide_info_entry;
246struct slide_info_entry_toc;
2d21ac55
A
247
248#endif /* MACH_KERNEL_PRIVATE */
249
f427ee49
A
250struct _sr_file_mappings {
251 int fd;
252 uint32_t mappings_count;
253 struct shared_file_mapping_slide_np *mappings;
254 uint32_t slide;
255 struct fileproc *fp;
256 struct vnode *vp;
257 memory_object_size_t file_size;
258 memory_object_control_t file_control;
259};
260
2d21ac55
A
261extern void vm_shared_region_init(void);
262extern kern_return_t vm_shared_region_enter(
0a7de745
A
263 struct _vm_map *map,
264 struct task *task,
265 boolean_t is_64bit,
266 void *fsroot,
267 cpu_type_t cpu,
f427ee49
A
268 cpu_subtype_t cpu_subtype,
269 boolean_t reslide);
2d21ac55 270extern kern_return_t vm_shared_region_remove(
0a7de745
A
271 struct _vm_map *map,
272 struct task *task);
2d21ac55 273extern vm_shared_region_t vm_shared_region_get(
0a7de745 274 struct task *task);
d9a64523 275extern vm_shared_region_t vm_shared_region_trim_and_get(
0a7de745 276 struct task *task);
2d21ac55 277extern void vm_shared_region_deallocate(
0a7de745 278 struct vm_shared_region *shared_region);
2d21ac55 279extern mach_vm_offset_t vm_shared_region_base_address(
0a7de745 280 struct vm_shared_region *shared_region);
2d21ac55 281extern mach_vm_size_t vm_shared_region_size(
0a7de745 282 struct vm_shared_region *shared_region);
2d21ac55 283extern ipc_port_t vm_shared_region_mem_entry(
0a7de745 284 struct vm_shared_region *shared_region);
d9a64523 285extern vm_map_t vm_shared_region_vm_map(
0a7de745 286 struct vm_shared_region *shared_region);
2d21ac55 287extern void vm_shared_region_set(
0a7de745
A
288 struct task *task,
289 struct vm_shared_region *new_shared_region);
2d21ac55 290extern vm_shared_region_t vm_shared_region_lookup(
0a7de745
A
291 void *root_dir,
292 cpu_type_t cpu,
293 cpu_subtype_t cpu_subtype,
f427ee49
A
294 boolean_t is_64bit,
295 boolean_t reslide);
2d21ac55 296extern kern_return_t vm_shared_region_start_address(
0a7de745
A
297 struct vm_shared_region *shared_region,
298 mach_vm_offset_t *start_address);
6d2010ae 299extern void vm_shared_region_undo_mappings(
0a7de745
A
300 vm_map_t sr_map,
301 mach_vm_offset_t sr_base_address,
f427ee49
A
302 struct _sr_file_mappings *srf_mappings,
303 struct _sr_file_mappings *srf_mappings_count,
0a7de745 304 unsigned int mappings_count);
f427ee49 305__attribute__((noinline))
2d21ac55 306extern kern_return_t vm_shared_region_map_file(
0a7de745 307 struct vm_shared_region *shared_region,
0a7de745 308 void *root_dir,
f427ee49
A
309 int sr_mappings_count,
310 struct _sr_file_mappings *sr_mappings);
6d2010ae 311extern kern_return_t vm_shared_region_sliding_valid(uint32_t slide);
2d21ac55 312extern void vm_commpage_init(void);
316670eb 313extern void vm_commpage_text_init(void);
2d21ac55 314extern kern_return_t vm_commpage_enter(
0a7de745
A
315 struct _vm_map *map,
316 struct task *task,
317 boolean_t is64bit);
2d21ac55 318extern kern_return_t vm_commpage_remove(
0a7de745
A
319 struct _vm_map *map,
320 struct task *task);
321int vm_shared_region_slide(uint32_t,
322 mach_vm_offset_t,
323 mach_vm_size_t,
324 mach_vm_offset_t,
325 mach_vm_size_t,
326 mach_vm_offset_t,
f427ee49
A
327 memory_object_control_t,
328 vm_prot_t);
329extern void vm_shared_region_pivot(void);
330extern void vm_shared_region_reslide_stale(void);
331#if __has_feature(ptrauth_calls)
332__attribute__((noinline))
333extern kern_return_t vm_shared_region_auth_remap(vm_shared_region_t sr);
334#endif /* __has_feature(ptrauth_calls) */
335extern void vm_shared_region_reference(vm_shared_region_t sr);
2d21ac55
A
336
337#endif /* KERNEL_PRIVATE */
338
0a7de745 339#endif /* _VM_SHARED_REGION_H_ */