1 /* 2 * Copyright (c) 2000-2020 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 * @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/pmap.h 60 * Author: Avadis Tevanian, Jr. 61 * Date: 1985 62 * 63 * Machine address mapping definitions -- machine-independent 64 * section. [For machine-dependent section, see "machine/pmap.h".] 65 */ 66 67 #ifndef _VM_PMAP_H_ 68 #define _VM_PMAP_H_ 69 70 #include <mach/kern_return.h> 71 #include <mach/vm_param.h> 72 #include <mach/vm_types.h> 73 #include <mach/vm_attributes.h> 74 #include <mach/boolean.h> 75 #include <mach/vm_prot.h> 76 #include <kern/trustcache.h> 77 78 #if __has_include(<CoreEntitlements/CoreEntitlements.h>) 79 #include <CoreEntitlements/CoreEntitlements.h> 80 #endif 81 82 #ifdef KERNEL_PRIVATE 83 84 /* 85 * The following is a description of the interface to the 86 * machine-dependent "physical map" data structure. The module 87 * must provide a "pmap_t" data type that represents the 88 * set of valid virtual-to-physical addresses for one user 89 * address space. [The kernel address space is represented 90 * by a distinguished "pmap_t".] The routines described manage 91 * this type, install and update virtual-to-physical mappings, 92 * and perform operations on physical addresses common to 93 * many address spaces. 94 */ 95 96 /* Copy between a physical page and a virtual address */ 97 /* LP64todo - switch to vm_map_offset_t when it grows */ 98 extern kern_return_t copypv( 99 addr64_t source, 100 addr64_t sink, 101 unsigned int size, 102 int which); 103 #define cppvPsnk 1 104 #define cppvPsnkb 31 105 #define cppvPsrc 2 106 #define cppvPsrcb 30 107 #define cppvFsnk 4 108 #define cppvFsnkb 29 109 #define cppvFsrc 8 110 #define cppvFsrcb 28 111 #define cppvNoModSnk 16 112 #define cppvNoModSnkb 27 113 #define cppvNoRefSrc 32 114 #define cppvNoRefSrcb 26 115 #define cppvKmap 64 /* Use the kernel's vm_map */ 116 #define cppvKmapb 25 117 118 extern boolean_t pmap_has_managed_page(ppnum_t first, ppnum_t last); 119 120 #if MACH_KERNEL_PRIVATE || BSD_KERNEL_PRIVATE 121 #include <mach/mach_types.h> 122 #include <vm/memory_types.h> 123 124 /* 125 * Routines used during BSD process creation. 126 */ 127 128 extern pmap_t pmap_create_options( /* Create a pmap_t. */ 129 ledger_t ledger, 130 vm_map_size_t size, 131 unsigned int flags); 132 133 #if __has_feature(ptrauth_calls) && (defined(XNU_TARGET_OS_OSX) || (DEVELOPMENT || DEBUG)) 134 /** 135 * Informs the pmap layer that a process will be running with user JOP disabled, 136 * as if PMAP_CREATE_DISABLE_JOP had been passed during pmap creation. 137 * 138 * @note This function cannot be used once the target process has started 139 * executing code. It is intended for cases where user JOP is disabled based on 140 * the code signature (e.g., special "keys-off" entitlements), which is too late 141 * to change the flags passed to pmap_create_options. 142 * 143 * @param pmap The pmap belonging to the target process 144 */ 145 extern void pmap_disable_user_jop( 146 pmap_t pmap); 147 #endif /* __has_feature(ptrauth_calls) && (defined(XNU_TARGET_OS_OSX) || (DEVELOPMENT || DEBUG)) */ 148 #endif /* MACH_KERNEL_PRIVATE || BSD_KERNEL_PRIVATE */ 149 150 #ifdef MACH_KERNEL_PRIVATE 151 152 #include <mach_assert.h> 153 154 #include <machine/pmap.h> 155 /* 156 * Routines used for initialization. 157 * There is traditionally also a pmap_bootstrap, 158 * used very early by machine-dependent code, 159 * but it is not part of the interface. 160 * 161 * LP64todo - 162 * These interfaces are tied to the size of the 163 * kernel pmap - and therefore use the "local" 164 * vm_offset_t, etc... types. 165 */ 166 167 extern void *pmap_steal_memory(vm_size_t size, vm_size_t alignment); /* Early memory allocation */ 168 extern void *pmap_steal_freeable_memory(vm_size_t size); /* Early memory allocation */ 169 extern void *pmap_steal_zone_memory(vm_size_t size, vm_size_t alignment); /* Early zone memory allocation */ 170 171 extern uint_t pmap_free_pages(void); /* report remaining unused physical pages */ 172 #if defined(__arm__) || defined(__arm64__) 173 extern uint_t pmap_free_pages_span(void); /* report phys address range of unused physical pages */ 174 #endif /* defined(__arm__) || defined(__arm64__) */ 175 176 extern void pmap_startup(vm_offset_t *startp, vm_offset_t *endp); /* allocate vm_page structs */ 177 178 extern void pmap_init(void); /* Initialization, once we have kernel virtual memory. */ 179 180 extern void mapping_adjust(void); /* Adjust free mapping count */ 181 182 extern void mapping_free_prime(void); /* Primes the mapping block release list */ 183 184 #ifndef MACHINE_PAGES 185 /* 186 * If machine/pmap.h defines MACHINE_PAGES, it must implement 187 * the above functions. The pmap module has complete control. 188 * Otherwise, it must implement the following functions: 189 * pmap_free_pages 190 * pmap_virtual_space 191 * pmap_next_page 192 * pmap_init 193 * and vm/vm_resident.c implements pmap_steal_memory and pmap_startup 194 * using pmap_free_pages, pmap_next_page, pmap_virtual_space, 195 * and pmap_enter. pmap_free_pages may over-estimate the number 196 * of unused physical pages, and pmap_next_page may return FALSE 197 * to indicate that there are no more unused pages to return. 198 * However, for best performance pmap_free_pages should be accurate. 199 */ 200 201 /* 202 * Routines to return the next unused physical page. 203 */ 204 extern boolean_t pmap_next_page(ppnum_t *pnum); 205 extern boolean_t pmap_next_page_hi(ppnum_t *pnum, boolean_t might_free); 206 #ifdef __x86_64__ 207 extern kern_return_t pmap_next_page_large(ppnum_t *pnum); 208 extern void pmap_hi_pages_done(void); 209 #endif 210 211 __enum_decl(pmap_mapping_type_t, uint8_t, { 212 PMAP_MAPPING_TYPE_INFER = 0, 213 PMAP_MAPPING_TYPE_DEFAULT, 214 PMAP_MAPPING_TYPE_ROZONE, 215 PMAP_MAPPING_TYPE_RESTRICTED 216 }); 217 218 /* 219 * Report virtual space available for the kernel. 220 */ 221 extern void pmap_virtual_space( 222 vm_offset_t *virtual_start, 223 vm_offset_t *virtual_end); 224 #endif /* MACHINE_PAGES */ 225 226 /* 227 * Routines to manage the physical map data structure. 228 */ 229 extern pmap_t(pmap_kernel)(void); /* Return the kernel's pmap */ 230 extern void pmap_reference(pmap_t pmap); /* Gain a reference. */ 231 extern void pmap_destroy(pmap_t pmap); /* Release a reference. */ 232 extern void pmap_switch(pmap_t); 233 extern void pmap_require(pmap_t pmap); 234 235 #if MACH_ASSERT 236 extern void pmap_set_process(pmap_t pmap, 237 int pid, 238 char *procname); 239 #endif /* MACH_ASSERT */ 240 241 extern kern_return_t pmap_enter( /* Enter a mapping */ 242 pmap_t pmap, 243 vm_map_offset_t v, 244 ppnum_t pn, 245 vm_prot_t prot, 246 vm_prot_t fault_type, 247 unsigned int flags, 248 boolean_t wired, 249 pmap_mapping_type_t mapping_type); 250 251 extern kern_return_t pmap_enter_options( 252 pmap_t pmap, 253 vm_map_offset_t v, 254 ppnum_t pn, 255 vm_prot_t prot, 256 vm_prot_t fault_type, 257 unsigned int flags, 258 boolean_t wired, 259 unsigned int options, 260 void *arg, 261 pmap_mapping_type_t mapping_type); 262 extern kern_return_t pmap_enter_options_addr( 263 pmap_t pmap, 264 vm_map_offset_t v, 265 pmap_paddr_t pa, 266 vm_prot_t prot, 267 vm_prot_t fault_type, 268 unsigned int flags, 269 boolean_t wired, 270 unsigned int options, 271 void *arg, 272 pmap_mapping_type_t mapping_type); 273 274 extern void pmap_remove_some_phys( 275 pmap_t pmap, 276 ppnum_t pn); 277 278 extern void pmap_lock_phys_page( 279 ppnum_t pn); 280 281 extern void pmap_unlock_phys_page( 282 ppnum_t pn); 283 284 285 /* 286 * Routines that operate on physical addresses. 287 */ 288 289 extern void pmap_page_protect( /* Restrict access to page. */ 290 ppnum_t phys, 291 vm_prot_t prot); 292 293 extern void pmap_page_protect_options( /* Restrict access to page. */ 294 ppnum_t phys, 295 vm_prot_t prot, 296 unsigned int options, 297 void *arg); 298 299 extern void(pmap_zero_page)( 300 ppnum_t pn); 301 302 extern void(pmap_zero_part_page)( 303 ppnum_t pn, 304 vm_offset_t offset, 305 vm_size_t len); 306 307 extern void(pmap_copy_page)( 308 ppnum_t src, 309 ppnum_t dest); 310 311 extern void(pmap_copy_part_page)( 312 ppnum_t src, 313 vm_offset_t src_offset, 314 ppnum_t dst, 315 vm_offset_t dst_offset, 316 vm_size_t len); 317 318 extern void(pmap_copy_part_lpage)( 319 vm_offset_t src, 320 ppnum_t dst, 321 vm_offset_t dst_offset, 322 vm_size_t len); 323 324 extern void(pmap_copy_part_rpage)( 325 ppnum_t src, 326 vm_offset_t src_offset, 327 vm_offset_t dst, 328 vm_size_t len); 329 330 extern unsigned int(pmap_disconnect)( /* disconnect mappings and return reference and change */ 331 ppnum_t phys); 332 333 extern unsigned int(pmap_disconnect_options)( /* disconnect mappings and return reference and change */ 334 ppnum_t phys, 335 unsigned int options, 336 void *arg); 337 338 extern kern_return_t(pmap_attribute_cache_sync)( /* Flush appropriate 339 * cache based on 340 * page number sent */ 341 ppnum_t pn, 342 vm_size_t size, 343 vm_machine_attribute_t attribute, 344 vm_machine_attribute_val_t* value); 345 346 extern unsigned int(pmap_cache_attributes)( 347 ppnum_t pn); 348 349 /* 350 * Set (override) cache attributes for the specified physical page 351 */ 352 extern void pmap_set_cache_attributes( 353 ppnum_t, 354 unsigned int); 355 356 extern void *pmap_map_compressor_page( 357 ppnum_t); 358 359 extern void pmap_unmap_compressor_page( 360 ppnum_t, 361 void*); 362 363 #if defined(__arm__) || defined(__arm64__) 364 extern bool pmap_batch_set_cache_attributes( 365 upl_page_info_array_t, 366 unsigned int, 367 unsigned int); 368 #endif 369 extern void pmap_sync_page_data_phys(ppnum_t pa); 370 extern void pmap_sync_page_attributes_phys(ppnum_t pa); 371 372 /* 373 * debug/assertions. pmap_verify_free returns true iff 374 * the given physical page is mapped into no pmap. 375 * pmap_assert_free() will panic() if pn is not free. 376 */ 377 extern bool pmap_verify_free(ppnum_t pn); 378 #if MACH_ASSERT 379 extern void pmap_assert_free(ppnum_t pn); 380 #endif 381 382 383 /* 384 * Sundry required (internal) routines 385 */ 386 #ifdef CURRENTLY_UNUSED_AND_UNTESTED 387 extern void pmap_collect(pmap_t pmap);/* Perform garbage 388 * collection, if any */ 389 #endif 390 /* 391 * Optional routines 392 */ 393 extern void(pmap_copy)( /* Copy range of mappings, 394 * if desired. */ 395 pmap_t dest, 396 pmap_t source, 397 vm_map_offset_t dest_va, 398 vm_map_size_t size, 399 vm_map_offset_t source_va); 400 401 extern kern_return_t(pmap_attribute)( /* Get/Set special memory 402 * attributes */ 403 pmap_t pmap, 404 vm_map_offset_t va, 405 vm_map_size_t size, 406 vm_machine_attribute_t attribute, 407 vm_machine_attribute_val_t* value); 408 409 /* 410 * Routines defined as macros. 411 */ 412 #ifndef PMAP_ACTIVATE_USER 413 #ifndef PMAP_ACTIVATE 414 #define PMAP_ACTIVATE_USER(thr, cpu) 415 #else /* PMAP_ACTIVATE */ 416 #define PMAP_ACTIVATE_USER(thr, cpu) { \ 417 pmap_t pmap; \ 418 \ 419 pmap = (thr)->map->pmap; \ 420 if (pmap != pmap_kernel()) \ 421 PMAP_ACTIVATE(pmap, (thr), (cpu)); \ 422 } 423 #endif /* PMAP_ACTIVATE */ 424 #endif /* PMAP_ACTIVATE_USER */ 425 426 #ifndef PMAP_DEACTIVATE_USER 427 #ifndef PMAP_DEACTIVATE 428 #define PMAP_DEACTIVATE_USER(thr, cpu) 429 #else /* PMAP_DEACTIVATE */ 430 #define PMAP_DEACTIVATE_USER(thr, cpu) { \ 431 pmap_t pmap; \ 432 \ 433 pmap = (thr)->map->pmap; \ 434 if ((pmap) != pmap_kernel()) \ 435 PMAP_DEACTIVATE(pmap, (thr), (cpu)); \ 436 } 437 #endif /* PMAP_DEACTIVATE */ 438 #endif /* PMAP_DEACTIVATE_USER */ 439 440 #ifndef PMAP_ACTIVATE_KERNEL 441 #ifndef PMAP_ACTIVATE 442 #define PMAP_ACTIVATE_KERNEL(cpu) 443 #else /* PMAP_ACTIVATE */ 444 #define PMAP_ACTIVATE_KERNEL(cpu) \ 445 PMAP_ACTIVATE(pmap_kernel(), THREAD_NULL, cpu) 446 #endif /* PMAP_ACTIVATE */ 447 #endif /* PMAP_ACTIVATE_KERNEL */ 448 449 #ifndef PMAP_DEACTIVATE_KERNEL 450 #ifndef PMAP_DEACTIVATE 451 #define PMAP_DEACTIVATE_KERNEL(cpu) 452 #else /* PMAP_DEACTIVATE */ 453 #define PMAP_DEACTIVATE_KERNEL(cpu) \ 454 PMAP_DEACTIVATE(pmap_kernel(), THREAD_NULL, cpu) 455 #endif /* PMAP_DEACTIVATE */ 456 #endif /* PMAP_DEACTIVATE_KERNEL */ 457 458 #ifndef PMAP_SET_CACHE_ATTR 459 #define PMAP_SET_CACHE_ATTR(mem, object, cache_attr, batch_pmap_op) \ 460 MACRO_BEGIN \ 461 if (!batch_pmap_op) { \ 462 pmap_set_cache_attributes(VM_PAGE_GET_PHYS_PAGE(mem), cache_attr); \ 463 object->set_cache_attr = TRUE; \ 464 } \ 465 MACRO_END 466 #endif /* PMAP_SET_CACHE_ATTR */ 467 468 #ifndef PMAP_BATCH_SET_CACHE_ATTR 469 #if defined(__arm__) || defined(__arm64__) 470 #define PMAP_BATCH_SET_CACHE_ATTR(object, user_page_list, \ 471 cache_attr, num_pages, batch_pmap_op) \ 472 MACRO_BEGIN \ 473 if ((batch_pmap_op)) { \ 474 (void)pmap_batch_set_cache_attributes( \ 475 (user_page_list), \ 476 (num_pages), \ 477 (cache_attr)); \ 478 (object)->set_cache_attr = TRUE; \ 479 } \ 480 MACRO_END 481 #else 482 #define PMAP_BATCH_SET_CACHE_ATTR(object, user_page_list, \ 483 cache_attr, num_pages, batch_pmap_op) \ 484 MACRO_BEGIN \ 485 if ((batch_pmap_op)) { \ 486 unsigned int __page_idx=0; \ 487 while (__page_idx < (num_pages)) { \ 488 pmap_set_cache_attributes( \ 489 user_page_list[__page_idx].phys_addr, \ 490 (cache_attr)); \ 491 __page_idx++; \ 492 } \ 493 (object)->set_cache_attr = TRUE; \ 494 } \ 495 MACRO_END 496 #endif 497 #endif /* PMAP_BATCH_SET_CACHE_ATTR */ 498 499 /* 500 * Routines to manage reference/modify bits based on 501 * physical addresses, simulating them if not provided 502 * by the hardware. 503 */ 504 struct pfc { 505 long pfc_cpus; 506 long pfc_invalid_global; 507 }; 508 509 typedef struct pfc pmap_flush_context; 510 511 /* Clear reference bit */ 512 extern void pmap_clear_reference(ppnum_t pn); 513 /* Return reference bit */ 514 extern boolean_t(pmap_is_referenced)(ppnum_t pn); 515 /* Set modify bit */ 516 extern void pmap_set_modify(ppnum_t pn); 517 /* Clear modify bit */ 518 extern void pmap_clear_modify(ppnum_t pn); 519 /* Return modify bit */ 520 extern boolean_t pmap_is_modified(ppnum_t pn); 521 /* Return modified and referenced bits */ 522 extern unsigned int pmap_get_refmod(ppnum_t pn); 523 /* Clear modified and referenced bits */ 524 extern void pmap_clear_refmod(ppnum_t pn, unsigned int mask); 525 #define VM_MEM_MODIFIED 0x01 /* Modified bit */ 526 #define VM_MEM_REFERENCED 0x02 /* Referenced bit */ 527 extern void pmap_clear_refmod_options(ppnum_t pn, unsigned int mask, unsigned int options, void *); 528 529 /* 530 * Clears the reference and/or modified bits on a range of virtually 531 * contiguous pages. 532 * It returns true if the operation succeeded. If it returns false, 533 * nothing has been modified. 534 * This operation is only supported on some platforms, so callers MUST 535 * handle the case where it returns false. 536 */ 537 extern bool 538 pmap_clear_refmod_range_options( 539 pmap_t pmap, 540 vm_map_address_t start, 541 vm_map_address_t end, 542 unsigned int mask, 543 unsigned int options); 544 545 546 extern void pmap_flush_context_init(pmap_flush_context *); 547 extern void pmap_flush(pmap_flush_context *); 548 549 /* 550 * Routines that operate on ranges of virtual addresses. 551 */ 552 extern void pmap_protect( /* Change protections. */ 553 pmap_t map, 554 vm_map_offset_t s, 555 vm_map_offset_t e, 556 vm_prot_t prot); 557 558 extern void pmap_protect_options( /* Change protections. */ 559 pmap_t map, 560 vm_map_offset_t s, 561 vm_map_offset_t e, 562 vm_prot_t prot, 563 unsigned int options, 564 void *arg); 565 566 extern void(pmap_pageable)( 567 pmap_t pmap, 568 vm_map_offset_t start, 569 vm_map_offset_t end, 570 boolean_t pageable); 571 572 extern uint64_t pmap_shared_region_size_min(pmap_t map); 573 574 extern kern_return_t pmap_nest(pmap_t, 575 pmap_t, 576 addr64_t, 577 uint64_t); 578 extern kern_return_t pmap_unnest(pmap_t, 579 addr64_t, 580 uint64_t); 581 582 #define PMAP_UNNEST_CLEAN 1 583 584 #if __arm64__ 585 #define PMAP_FORK_NEST 1 586 extern kern_return_t pmap_fork_nest( 587 pmap_t old_pmap, 588 pmap_t new_pmap, 589 vm_map_offset_t *nesting_start, 590 vm_map_offset_t *nesting_end); 591 #endif /* __arm64__ */ 592 593 extern kern_return_t pmap_unnest_options(pmap_t, 594 addr64_t, 595 uint64_t, 596 unsigned int); 597 extern boolean_t pmap_adjust_unnest_parameters(pmap_t, vm_map_offset_t *, vm_map_offset_t *); 598 extern void pmap_advise_pagezero_range(pmap_t, uint64_t); 599 #endif /* MACH_KERNEL_PRIVATE */ 600 601 extern boolean_t pmap_is_noencrypt(ppnum_t); 602 extern void pmap_set_noencrypt(ppnum_t pn); 603 extern void pmap_clear_noencrypt(ppnum_t pn); 604 605 /* 606 * JMM - This portion is exported to other kernel components right now, 607 * but will be pulled back in the future when the needed functionality 608 * is provided in a cleaner manner. 609 */ 610 611 extern const pmap_t kernel_pmap; /* The kernel's map */ 612 #define pmap_kernel() (kernel_pmap) 613 614 #define VM_MEM_SUPERPAGE 0x100 /* map a superpage instead of a base page */ 615 #define VM_MEM_STACK 0x200 616 617 /* N.B. These use the same numerical space as the PMAP_EXPAND_OPTIONS 618 * definitions in i386/pmap_internal.h 619 */ 620 #define PMAP_CREATE_64BIT 0x1 621 622 #if __x86_64__ 623 624 #define PMAP_CREATE_EPT 0x2 625 #define PMAP_CREATE_TEST 0x4 /* pmap will be used for testing purposes only */ 626 #define PMAP_CREATE_KNOWN_FLAGS (PMAP_CREATE_64BIT | PMAP_CREATE_EPT | PMAP_CREATE_TEST) 627 628 #else 629 630 #define PMAP_CREATE_STAGE2 0 631 #if __arm64e__ 632 #define PMAP_CREATE_DISABLE_JOP 0x4 633 #else 634 #define PMAP_CREATE_DISABLE_JOP 0 635 #endif 636 #if __ARM_MIXED_PAGE_SIZE__ 637 #define PMAP_CREATE_FORCE_4K_PAGES 0x8 638 #else 639 #define PMAP_CREATE_FORCE_4K_PAGES 0 640 #endif /* __ARM_MIXED_PAGE_SIZE__ */ 641 #define PMAP_CREATE_X86_64 0 642 #if CONFIG_ROSETTA 643 #define PMAP_CREATE_ROSETTA 0x20 644 #else 645 #define PMAP_CREATE_ROSETTA 0 646 #endif /* CONFIG_ROSETTA */ 647 648 #define PMAP_CREATE_TEST 0x40 /* pmap will be used for testing purposes only */ 649 650 /* Define PMAP_CREATE_KNOWN_FLAGS in terms of optional flags */ 651 #define PMAP_CREATE_KNOWN_FLAGS (PMAP_CREATE_64BIT | PMAP_CREATE_STAGE2 | PMAP_CREATE_DISABLE_JOP | \ 652 PMAP_CREATE_FORCE_4K_PAGES | PMAP_CREATE_X86_64 | PMAP_CREATE_ROSETTA | PMAP_CREATE_TEST) 653 654 #endif /* __x86_64__ */ 655 656 #define PMAP_OPTIONS_NOWAIT 0x1 /* don't block, return 657 * KERN_RESOURCE_SHORTAGE 658 * instead */ 659 #define PMAP_OPTIONS_NOENTER 0x2 /* expand pmap if needed 660 * but don't enter mapping 661 */ 662 #define PMAP_OPTIONS_COMPRESSOR 0x4 /* credit the compressor for 663 * this operation */ 664 #define PMAP_OPTIONS_INTERNAL 0x8 /* page from internal object */ 665 #define PMAP_OPTIONS_REUSABLE 0x10 /* page is "reusable" */ 666 #define PMAP_OPTIONS_NOFLUSH 0x20 /* delay flushing of pmap */ 667 #define PMAP_OPTIONS_NOREFMOD 0x40 /* don't need ref/mod on disconnect */ 668 #define PMAP_OPTIONS_ALT_ACCT 0x80 /* use alternate accounting scheme for page */ 669 #define PMAP_OPTIONS_REMOVE 0x100 /* removing a mapping */ 670 #define PMAP_OPTIONS_SET_REUSABLE 0x200 /* page is now "reusable" */ 671 #define PMAP_OPTIONS_CLEAR_REUSABLE 0x400 /* page no longer "reusable" */ 672 #define PMAP_OPTIONS_COMPRESSOR_IFF_MODIFIED 0x800 /* credit the compressor 673 * iff page was modified */ 674 #define PMAP_OPTIONS_PROTECT_IMMEDIATE 0x1000 /* allow protections to be 675 * be upgraded */ 676 #define PMAP_OPTIONS_CLEAR_WRITE 0x2000 677 #define PMAP_OPTIONS_TRANSLATED_ALLOW_EXECUTE 0x4000 /* Honor execute for translated processes */ 678 #if defined(__arm__) || defined(__arm64__) 679 #define PMAP_OPTIONS_FF_LOCKED 0x8000 680 #define PMAP_OPTIONS_FF_WIRED 0x10000 681 #endif 682 #define PMAP_OPTIONS_XNU_USER_DEBUG 0x20000 683 684 #define PMAP_OPTIONS_MAP_TPRO 0x40000 685 686 #define PMAP_OPTIONS_RESERVED_MASK 0xFF000000 /* encoding space reserved for internal pmap use */ 687 688 #if !defined(__LP64__) 689 extern vm_offset_t pmap_extract(pmap_t pmap, 690 vm_map_offset_t va); 691 #endif 692 extern void pmap_change_wiring( /* Specify pageability */ 693 pmap_t pmap, 694 vm_map_offset_t va, 695 boolean_t wired); 696 697 /* LP64todo - switch to vm_map_offset_t when it grows */ 698 extern void pmap_remove( /* Remove mappings. */ 699 pmap_t map, 700 vm_map_offset_t s, 701 vm_map_offset_t e); 702 703 extern void pmap_remove_options( /* Remove mappings. */ 704 pmap_t map, 705 vm_map_offset_t s, 706 vm_map_offset_t e, 707 int options); 708 709 extern void fillPage(ppnum_t pa, unsigned int fill); 710 711 #if defined(__LP64__) 712 extern void pmap_pre_expand(pmap_t pmap, vm_map_offset_t vaddr); 713 extern kern_return_t pmap_pre_expand_large(pmap_t pmap, vm_map_offset_t vaddr); 714 extern vm_size_t pmap_query_pagesize(pmap_t map, vm_map_offset_t vaddr); 715 #endif 716 717 mach_vm_size_t pmap_query_resident(pmap_t pmap, 718 vm_map_offset_t s, 719 vm_map_offset_t e, 720 mach_vm_size_t *compressed_bytes_p); 721 722 extern void pmap_set_vm_map_cs_enforced(pmap_t pmap, bool new_value); 723 extern bool pmap_get_vm_map_cs_enforced(pmap_t pmap); 724 725 /* Inform the pmap layer that there is a JIT entry in this map. */ 726 extern void pmap_set_jit_entitled(pmap_t pmap); 727 728 /* Ask the pmap layer if there is a JIT entry in this map. */ 729 extern bool pmap_get_jit_entitled(pmap_t pmap); 730 731 /* Inform the pmap layer that the XO register is repurposed for this map */ 732 extern void pmap_set_tpro(pmap_t pmap); 733 734 /* Ask the pmap layer if there is a TPRO entry in this map. */ 735 extern bool pmap_get_tpro(pmap_t pmap); 736 737 /* 738 * Tell the pmap layer what range within the nested region the VM intends to 739 * use. 740 */ 741 extern void pmap_trim(pmap_t grand, pmap_t subord, addr64_t vstart, uint64_t size); 742 743 extern bool pmap_is_nested(pmap_t pmap); 744 745 /* 746 * Dump page table contents into the specified buffer. Returns KERN_INSUFFICIENT_BUFFER_SIZE 747 * if insufficient space, KERN_NOT_SUPPORTED if unsupported in the current configuration. 748 * This is expected to only be called from kernel debugger context, 749 * so synchronization is not required. 750 */ 751 752 extern kern_return_t pmap_dump_page_tables(pmap_t pmap, void *bufp, void *buf_end, unsigned int level_mask, size_t *bytes_copied); 753 754 /* Asks the pmap layer for number of bits used for VA address. */ 755 extern uint32_t pmap_user_va_bits(pmap_t pmap); 756 extern uint32_t pmap_kernel_va_bits(void); 757 758 /* 759 * Indicates if any special policy is applied to this protection by the pmap 760 * layer. 761 */ 762 bool pmap_has_prot_policy(pmap_t pmap, bool translated_allow_execute, vm_prot_t prot); 763 764 /* 765 * Causes the pmap to return any available pages that it can return cheaply to 766 * the VM. 767 */ 768 uint64_t pmap_release_pages_fast(void); 769 770 #define PMAP_QUERY_PAGE_PRESENT 0x01 771 #define PMAP_QUERY_PAGE_REUSABLE 0x02 772 #define PMAP_QUERY_PAGE_INTERNAL 0x04 773 #define PMAP_QUERY_PAGE_ALTACCT 0x08 774 #define PMAP_QUERY_PAGE_COMPRESSED 0x10 775 #define PMAP_QUERY_PAGE_COMPRESSED_ALTACCT 0x20 776 extern kern_return_t pmap_query_page_info( 777 pmap_t pmap, 778 vm_map_offset_t va, 779 int *disp); 780 781 extern bool pmap_in_ppl(void); 782 783 extern uint32_t pmap_lookup_in_static_trust_cache(const uint8_t cdhash[CS_CDHASH_LEN]); 784 extern bool pmap_lookup_in_loaded_trust_caches(const uint8_t cdhash[CS_CDHASH_LEN]); 785 786 /** 787 * Indicates whether the device supports register-level MMIO access control. 788 * 789 * @note Unlike the pmap-io-ranges mechanism, which enforces PPL-only register 790 * writability at page granularity, this mechanism allows specific registers 791 * on a read-mostly page to be written using a dedicated guarded mode trap 792 * without requiring a full PPL driver extension. 793 * 794 * @return True if the device supports register-level MMIO access control. 795 */ 796 extern bool pmap_has_iofilter_protected_write(void); 797 798 /** 799 * Performs a write to the I/O register specified by addr on supported devices. 800 * 801 * @note On supported devices (determined by pmap_has_iofilter_protected_write()), this 802 * function goes over the sorted I/O filter entry table. If there is a hit, the 803 * write is performed from Guarded Mode. Otherwise, the write is performed from 804 * Normal Mode (kernel mode). Note that you can still hit an exception if the 805 * register is owned by PPL but not allowed by an io-filter-entry in the device tree. 806 * 807 * @note On unsupported devices, this function will panic. 808 * 809 * @param addr The address of the register. 810 * @param value The value to be written. 811 * @param width The width of the I/O register, supported values are 1, 2, 4 and 8. 812 */ 813 extern void pmap_iofilter_protected_write(vm_address_t addr, uint64_t value, uint64_t width); 814 815 extern void *pmap_claim_reserved_ppl_page(void); 816 extern void pmap_free_reserved_ppl_page(void *kva); 817 818 extern void pmap_ledger_verify_size(size_t); 819 extern ledger_t pmap_ledger_alloc(void); 820 extern void pmap_ledger_free(ledger_t); 821 822 extern bool pmap_is_bad_ram(ppnum_t ppn); 823 824 #if __arm64__ 825 extern bool pmap_is_exotic(pmap_t pmap); 826 #else /* __arm64__ */ 827 #define pmap_is_exotic(pmap) false 828 #endif /* __arm64__ */ 829 830 831 /* 832 * Returns a subset of pmap_cs non-default configuration, 833 * e.g. loosening up of some restrictions through pmap_cs or amfi 834 * boot-args. The return value is a bit field with possible bits 835 * described below. If default, the function will return 0. Note that 836 * this does not work the other way: 0 does not imply that pmap_cs 837 * runs in default configuration, and only a small configuration 838 * subset is returned by this function. 839 * 840 * Never assume the system is "secure" if this returns 0. 841 */ 842 extern int pmap_cs_configuration(void); 843 844 #if XNU_KERNEL_PRIVATE 845 846 #if defined(__arm64__) 847 848 /** 849 * Check if a particular pmap is used for stage2 translations or not. 850 */ 851 extern bool 852 pmap_performs_stage2_translations(const pmap_t pmap); 853 854 #endif /* defined(__arm64__) */ 855 #endif /* XNU_KERNEL_PRIVATE */ 856 857 858 859 #endif /* KERNEL_PRIVATE */ 860 861 #endif /* _VM_PMAP_H_ */ 862