Loading...
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
/*
 * Copyright (c) 2007 Apple Inc. All rights reserved.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. The rights granted to you under the License
 * may not be used to create, or enable the creation or redistribution of,
 * unlawful or unlicensed copies of an Apple operating system, or to
 * circumvent, violate, or enable the circumvention or violation of, any
 * terms of an Apple operating system software license agreement.
 *
 * Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 */
/*
 * FILE_ID: vm_param.h
 */

/*
 *	ARM machine dependent virtual memory parameters.
 */

#ifndef _MACH_ARM_VM_PARAM_H_
#define _MACH_ARM_VM_PARAM_H_

#if defined (__arm__) || defined (__arm64__)

#if defined(XNU_KERNEL_PRIVATE) && defined(__arm64__)
#include <arm64/proc_reg.h>
#endif

#if defined(KERNEL_PRIVATE) && __ARM_16K_PG__
#include <arm64/proc_reg.h>
#endif

#if !defined (KERNEL) && !defined (__ASSEMBLER__)
#include <mach/vm_page_size.h>
#endif

#define BYTE_SIZE       8       /* byte size in bits */

#if defined (KERNEL)

#ifndef __ASSEMBLER__

#ifdef  __arm__
#define PAGE_SHIFT_CONST        12
#elif defined(__arm64__)
extern int PAGE_SHIFT_CONST;
#else
#error Unsupported arch
#endif

#if defined(KERNEL_PRIVATE) && __ARM_16K_PG__
#define PAGE_SHIFT              ARM_PGSHIFT
#else
#define PAGE_SHIFT              PAGE_SHIFT_CONST
#endif
#define PAGE_SIZE               (1 << PAGE_SHIFT)
#define PAGE_MASK               (PAGE_SIZE-1)

#define VM_PAGE_SIZE            PAGE_SIZE

#define machine_ptob(x)         ((x) << PAGE_SHIFT)

/*
 * Defined for the purpose of testing the pmap advertised page
 * size; this does not necessarily match the hardware page size.
 */
#define TEST_PAGE_SIZE_16K      ((PAGE_SHIFT_CONST == 14))
#define TEST_PAGE_SIZE_4K       ((PAGE_SHIFT_CONST == 12))

#endif  /* !__ASSEMBLER__ */

#else

#define PAGE_SHIFT                      vm_page_shift
#define PAGE_SIZE                       vm_page_size
#define PAGE_MASK                       vm_page_mask

#define VM_PAGE_SIZE            vm_page_size

#define machine_ptob(x)         ((x) << PAGE_SHIFT)

#endif

#define PAGE_MAX_SHIFT          14
#define PAGE_MAX_SIZE           (1 << PAGE_MAX_SHIFT)
#define PAGE_MAX_MASK           (PAGE_MAX_SIZE-1)

#define PAGE_MIN_SHIFT          12
#define PAGE_MIN_SIZE           (1 << PAGE_MIN_SHIFT)
#define PAGE_MIN_MASK           (PAGE_MIN_SIZE-1)

#define VM_MAX_PAGE_ADDRESS     MACH_VM_MAX_ADDRESS

#ifndef __ASSEMBLER__

#ifdef  MACH_KERNEL_PRIVATE

#define VM32_SUPPORT            1
#define VM32_MIN_ADDRESS        ((vm32_offset_t) 0)
#define VM32_MAX_ADDRESS        ((vm32_offset_t) (VM_MAX_ADDRESS & 0xFFFFFFFF))

#endif /* MACH_KERNEL_PRIVATE */

#if defined (__arm__)

#define VM_MIN_ADDRESS          ((vm_address_t) 0x00000000)
#define VM_MAX_ADDRESS          ((vm_address_t) 0x80000000)

/* system-wide values */
#define MACH_VM_MIN_ADDRESS     ((mach_vm_offset_t) 0)
#define MACH_VM_MAX_ADDRESS     ((mach_vm_offset_t) VM_MAX_ADDRESS)

#elif defined (__arm64__)

#define VM_MIN_ADDRESS          ((vm_address_t) 0x0000000000000000ULL)
#define VM_MAX_ADDRESS          ((vm_address_t) 0x00000000F0000000ULL)

/* system-wide values */
#define MACH_VM_MIN_ADDRESS_RAW 0x0ULL
#if defined(XNU_PLATFORM_MacOSX) || defined(XNU_PLATFORM_DriverKit)
#define MACH_VM_MAX_ADDRESS_RAW 0x00007FFFFE000000ULL
#else
#define MACH_VM_MAX_ADDRESS_RAW 0x0000000FC0000000ULL
#endif

/*
 * `MACH_VM_MAX_ADDRESS` is exported to user space, but we don't want this
 * larger value for `MACH_VM_MAX_ADDRESS` to be exposed outside the kernel.
 */
#if XNU_KERNEL_PRIVATE
#if defined(XNU_PLATFORM_iPhoneOS) && EXTENDED_USER_VA_SUPPORT
#undef MACH_VM_MAX_ADDRESS_RAW
#define MACH_VM_MAX_ADDRESS_RAW 0x00007FFFFE000000ULL
#endif /* defined(XNU_PLATFORM_iPhoneOS) && EXTENDED_USER_VA_SUPPORT */
/* threshold for allocations to be placed in the large file range */
#define VM_LARGE_FILE_THRESHOLD (1ULL << 30)
#define MACH_VM_JUMBO_ADDRESS ((mach_vm_offset_t) 0x0000000FC0000000ULL)
#endif /* KERNEL_PRIVATE */

#define MACH_VM_MIN_ADDRESS     ((mach_vm_offset_t) MACH_VM_MIN_ADDRESS_RAW)
#define MACH_VM_MAX_ADDRESS     ((mach_vm_offset_t) MACH_VM_MAX_ADDRESS_RAW)

#define MACH_VM_MIN_GPU_CARVEOUT_ADDRESS_RAW 0x0000001000000000ULL
#define MACH_VM_MAX_GPU_CARVEOUT_ADDRESS_RAW 0x0000007000000000ULL
#define MACH_VM_MIN_GPU_CARVEOUT_ADDRESS     ((mach_vm_offset_t) MACH_VM_MIN_GPU_CARVEOUT_ADDRESS_RAW)
#define MACH_VM_MAX_GPU_CARVEOUT_ADDRESS     ((mach_vm_offset_t) MACH_VM_MAX_GPU_CARVEOUT_ADDRESS_RAW)

#else /* defined(__arm64__) */
#error architecture not supported
#endif

#define VM_MAP_MIN_ADDRESS      VM_MIN_ADDRESS
#define VM_MAP_MAX_ADDRESS      VM_MAX_ADDRESS

#ifdef  KERNEL

#if defined (__arm__)
#define VM_KERNEL_POINTER_SIGNIFICANT_BITS  31
#define VM_MIN_KERNEL_ADDRESS   ((vm_address_t) 0x80000000)
#define VM_MAX_KERNEL_ADDRESS   ((vm_address_t) 0xFFFEFFFF)
#define VM_HIGH_KERNEL_WINDOW   ((vm_address_t) 0xFFFE0000)

#elif defined (__arm64__)
/*
 * kalloc() parameters:
 *
 * Historically kalloc's underlying zones were power-of-2 sizes, with a
 * KALLOC_MINSIZE of 16 bytes.  Thus the allocator ensured that
 * (sizeof == alignof) >= 16 for all kalloc allocations.
 *
 * Today kalloc may use zones with intermediate (small) sizes, constrained by
 * KALLOC_MINSIZE and a minimum alignment, expressed by KALLOC_LOG2_MINALIGN.
 *
 * Note that most dynamically allocated data structures contain more than
 * one int/long/pointer member, so KALLOC_MINSIZE should probably start at 8.
 */
#define TiB(x)                  ((0ULL + (x)) << 40)
#define GiB(x)                  ((0ULL + (x)) << 30)
#define KALLOC_MINSIZE          16      /* minimum allocation size */
#define KALLOC_LOG2_MINALIGN    4       /* log2 minimum alignment */

/*
 * The minimum and maximum kernel address; some configurations may
 * constrain the address space further.
 */


#ifndef __BUILDING_XNU_LIBRARY__
#if XNU_KERNEL_PRIVATE
#if defined(ARM_LARGE_MEMORY)
/*
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_fed0_0000_0000 |-1216GB |  832GB | KASAN_SHADOW_MIN       |
 * | 0xffff_fecf_ffff_ffff |        |        | VM_MAX_KERNEL_ADDRESS  |
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_fe10_0000_0000 |-1984GB |   64GB | PMAP_HEAP_RANGE_START  |
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_fe00_0700_4000 |        |        | VM_KERNEL_LINK_ADDRESS |
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_fe00_0000_0000 |-2048GB |    0GB | VM_MIN_KERNEL_ADDRESS  |
 * |                       |        |        | LOW_GLOBALS            |
 * +-----------------------+--------+--------+------------------------+
 */
#define VM_KERNEL_POINTER_SIGNIFICANT_BITS  41

// Kernel VA space starts at -2TB
#define VM_MIN_KERNEL_ADDRESS   ((vm_address_t) (0ULL - TiB(2)))

//   64 GB for kernel cache and globals
//  768 GB for heap/general kernel use
// 1216 GB left over at the top of the range for KASAN
//     Assuming KASAN TBI, this lets us cover down to:
//     0 - (1216GB<<KASAN_SCALE) = 0xffff_ed00_0000_0000, or ~19.5TB of VA
//     Since we place the DRAM PAPT below VM_MIN_KERNEL_ADDRESS on large
//     memory configurations, this configuration works until systems have
//     ~17.5TB of DRAM.
#define VM_MAX_KERNEL_ADDRESS \
	((vm_address_t) (VM_MIN_KERNEL_ADDRESS + GiB(64) + GiB(768) - 1))

#else // ARM_LARGE_MEMORY
/*
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_fffc_0000_0000 |  -16GB |  112GB | KASAN_SHADOW_MIN       |
 * |                       |        |        | VM_MAX_KERNEL_ADDRESS  |
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_fff0_0700_4000 |        |        | VM_KERNEL_LINK_ADDRESS |
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_fff0_0000_0000 |  -64GB |   64GB | LOW_GLOBALS            |
 * |                       |        |        | PMAP_HEAP_RANGE_START  | <= H8
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_ffe0_0000_0000 | -128GB |    0GB | VM_MIN_KERNEL_ADDRESS  | <= H8
 * +-----------------------+--------+--------+------------------------+
 * | 0xffff_ffdc_0000_0000 | -144GB |    0GB | VM_MIN_KERNEL_ADDRESS  | >= H9
 * |                       |        |        | PMAP_HEAP_RANGE_START  | >= H9
 * +-----------------------+--------+--------+------------------------+
 */
#if defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR) || defined(KERNEL_INTEGRITY_PV_CTRR)
#define VM_KERNEL_POINTER_SIGNIFICANT_BITS  38
#define VM_MIN_KERNEL_ADDRESS   ((vm_address_t) (0ULL - GiB(144)))
#else /* defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR) || defined(KERNEL_INTEGRITY_PV_CTRR) */
#define VM_KERNEL_POINTER_SIGNIFICANT_BITS  37
#define VM_MIN_KERNEL_ADDRESS   ((vm_address_t) 0xffffffe000000000ULL)
#endif /* defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR) || defined(KERNEL_INTEGRITY_PV_CTRR) */
#define VM_MAX_KERNEL_ADDRESS   ((vm_address_t) 0xfffffffbffffffffULL)

#endif // ARM_LARGE_MEMORY

#else // !XNU_KERNEL_PRIVATE
// Inform kexts about largest possible kernel address space
#define VM_KERNEL_POINTER_SIGNIFICANT_BITS  41
#define VM_MIN_KERNEL_ADDRESS   ((vm_address_t) (0ULL - TiB(2)))
#define VM_MAX_KERNEL_ADDRESS   ((vm_address_t) 0xfffffffbffffffffULL)
#endif // XNU_KERNEL_PRIVATE
#else /* __BUILDING_XNU_LIBRARY__ */
#define VM_MIN_KERNEL_ADDRESS ((vm_address_t)(0x100000000ULL))
#define VM_MAX_KERNEL_ADDRESS ((vm_address_t)(0ULL + GiB(2)))
#define VM_KERNEL_POINTER_SIGNIFICANT_BITS  31
#endif /*__BUILDING_XNU_LIBRARY__ */
#else
#error architecture not supported
#endif

#define VM_MIN_KERNEL_AND_KEXT_ADDRESS  VM_MIN_KERNEL_ADDRESS

#if defined (__arm64__)
/* Top-Byte-Ignore */
#define ARM_TBI_USER_MASK        (0xFF00000000000000ULL)
#define VM_USER_STRIP_TBI(_v)    ((typeof (_v))(((uintptr_t)(_v)) &~ (ARM_TBI_USER_MASK)))
#else /* __arm64__ */
#define VM_USER_STRIP_TBI(_v)    (_v)
#endif /* __arm64__ */


#if __arm64__

#if XNU_KERNEL_PRIVATE
#define VM_KERNEL_STRIP_MASK            (-1ULL << (64 - T1SZ_BOOT))
#define VM_USER_STRIP_MASK              (-1ULL >> (T0SZ_BOOT))
#define _VM_KERNEL_STRIP_PTR(_va)       ({((_va) & 1ULL << 55) ? ((_va) | VM_KERNEL_STRIP_MASK) : ((_va) & VM_USER_STRIP_MASK);})
#else /* XNU_KERNEL_PRIVATE */

#if __has_feature(ptrauth_calls)
#include <ptrauth.h>
#define VM_KERNEL_STRIP_PAC(_v)         ((uintptr_t)(ptrauth_strip((void *)(uintptr_t)(_v), ptrauth_key_asia)))
#else /* !ptrauth_calls */
#define VM_KERNEL_STRIP_PAC(_v)         (_v)
#endif /* ptrauth_calls */
/* For KEXT, just blow away TBI bits, even if only used for KASAN. */
#define _VM_KERNEL_STRIP_PTR(_v)        (VM_KERNEL_STRIP_PAC(_v) | (0xFF00000000000000ULL))
#endif /* XNU_KERNEL_PRIVATE */

#else /* __arm64__ */
#define _VM_KERNEL_STRIP_PTR(_v)        (_v)
#endif /* __arm64__ */

#define VM_KERNEL_STRIP_PTR(_va)        (_VM_KERNEL_STRIP_PTR((uintptr_t)(_va)))

/* Vestige from the past, kept for retro-compatibility. */
#define VM_KERNEL_STRIP_UPTR(_va)       (VM_KERNEL_STRIP_PTR(_va))

#define VM_KERNEL_ADDRESS(_va)  \
	((VM_KERNEL_STRIP_PTR(_va) >= VM_MIN_KERNEL_ADDRESS) && \
	 (VM_KERNEL_STRIP_PTR(_va) <= VM_MAX_KERNEL_ADDRESS))

#define VM_USER_STRIP_PTR(_v)           (VM_USER_STRIP_TBI(_v))

#if DEBUG || DEVELOPMENT || !defined(HAS_APPLE_PAC)

#define ML_ADDRPERM(addr, slide) ((addr) + (slide))

#else /* DEBUG || DEVELOPMENT || !defined(HAS_APPLE_PAC) */

/**
 * While these function's implementations are machine specific, due to the need
 * to prevent header file circular dependencies, they need to be externed here
 * for usage in the addrperm macro
 */
__BEGIN_DECLS
vm_offset_t ml_addrperm_pacga(vm_offset_t addr);
__END_DECLS

#define ML_ADDRPERM(addr, slide) ml_addrperm_pacga(addr)

#endif /* DEBUG || DEVELOPMENT || !defined(HAS_APPLE_PAC) */

#ifdef  MACH_KERNEL_PRIVATE
/*
 *	Physical memory is mapped linearly at an offset virtual memory.
 */
extern unsigned long            gVirtBase, gPhysBase, gPhysSize;

#define isphysmem(a)            (((vm_address_t)(a) - gPhysBase) < gPhysSize)
#define physmap_enclosed(a)     isphysmem(a)

/*
 * gPhysBase/Size only represent kernel-managed memory. These globals represent
 * the actual DRAM base address and size as reported by iBoot through the device
 * tree.
 */
#include <stdint.h>
extern uint64_t                 gDramBase, gDramSize;
#define is_dram_addr(addr)      (((uint64_t)(addr) - gDramBase) < gDramSize)

#endif /* MACH_KERNEL_PRIVATE */

#ifdef  XNU_KERNEL_PRIVATE

#if KASAN
/* Increase the stack sizes to account for the redzones that get added to every
 * stack object. */
# define KERNEL_STACK_SIZE      (4*4*4096)
#elif DEBUG
/**
 * Increase the stack size to account for less efficient use of stack space when
 * compiling with -O0.
 */
# define KERNEL_STACK_SIZE      (2*4*4096)
#else
/*
 * KERNEL_STACK_MULTIPLIER can be defined externally to get a larger
 * kernel stack size. For example, adding "-DKERNEL_STACK_MULTIPLIER=2"
 * helps avoid kernel stack overflows when compiling with "-O0".
 */
#ifndef KERNEL_STACK_MULTIPLIER
#define KERNEL_STACK_MULTIPLIER (1)
#endif /* KERNEL_STACK_MULTIPLIER */
# define KERNEL_STACK_SIZE      (4*4096*KERNEL_STACK_MULTIPLIER)
#endif /* XNU_KERNEL_PRIVATE */

#define INTSTACK_SIZE           (4*4096)

#ifdef __arm64__
#define EXCEPSTACK_SIZE         (4*4096)
#else
#define FIQSTACK_SIZE           (4096)
#endif

#if defined (__arm__)
#define HIGH_EXC_VECTORS        ((vm_address_t) 0xFFFF0000)
#endif

/*
 * TODO: We're hardcoding the expected virtual TEXT base here;
 * that gives us an ugly dependency on a linker argument in
 * the make files.  Clean this up, so we don't hardcode it
 * twice; this is nothing but trouble.
 */
#if defined (__arm__)
#define VM_KERNEL_LINK_ADDRESS  ((vm_address_t) 0x80000000)
#elif defined (__arm64__)
/* VM_KERNEL_LINK_ADDRESS defined in makedefs/MakeInc.def for arm64 platforms */
#else
#error architecture not supported
#endif

#endif  /* MACH_KERNEL_PRIVATE */
#endif  /* KERNEL */

#endif  /* !__ASSEMBLER__ */

#define SWI_SYSCALL     0x80

#endif /* defined (__arm__) || defined (__arm64__) */

#endif  /* _MACH_ARM_VM_PARAM_H_ */