1.\" $NetBSD: pmap.9,v 1.37 2008/12/09 20:49:40 pooka Exp $ 2.\" 3.\" Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Jason R. Thorpe. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd December 9, 2008 31.Dt PMAP 9 32.Os 33.Sh NAME 34.Nm pmap 35.Nd machine-dependent portion of the virtual memory system 36.Sh SYNOPSIS 37.In sys/param.h 38.In uvm/uvm_extern.h 39.Ft void 40.Fn "pmap_init" "void" 41.Ft void 42.Fn "pmap_virtual_space" "vaddr_t *vstartp" "vaddr_t *vendp" 43.Ft vaddr_t 44.Fn "pmap_steal_memory" "vsize_t size" "vaddr_t *vstartp" "vaddr_t *vendp" 45.Ft pmap_t 46.Fn "pmap_kernel" "void" 47.Ft pmap_t 48.Fn "pmap_create" "void" 49.Ft void 50.Fn "pmap_destroy" "pmap_t pmap" 51.Ft void 52.Fn "pmap_reference" "pmap_t pmap" 53.Ft void 54.Fn "pmap_fork" "pmap_t src_map" "pmap_t dst_map" 55.Ft long 56.Fn "pmap_resident_count" "pmap_t pmap" 57.Ft long 58.Fn "pmap_wired_count" "pmap_t pmap" 59.Ft vaddr_t 60.Fn "pmap_growkernel" "vaddr_t maxkvaddr" 61.Ft int 62.Fn "pmap_enter" "pmap_t pmap" "vaddr_t va" "paddr_t pa" "vm_prot_t prot" \ 63 "int flags" 64.Ft void 65.Fn "pmap_remove" "pmap_t pmap" "vaddr_t sva" "vaddr_t eva" 66.Ft void 67.Fn "pmap_remove_all" "pmap_t pmap" 68.Ft void 69.Fn "pmap_protect" "pmap_t pmap" "vaddr_t sva" "vaddr_t eva" "vm_prot_t prot" 70.Ft void 71.Fn "pmap_unwire" "pmap_t pmap" "vaddr_t va" 72.Ft bool 73.Fn "pmap_extract" "pmap_t pmap" "vaddr_t va" "paddr_t *pap" 74.Ft void 75.Fn "pmap_kenter_pa" "vaddr_t va" "paddr_t pa" "vm_prot_t prot" 76.Ft void 77.Fn "pmap_kremove" "vaddr_t va" "vsize_t size" 78.Ft void 79.Fn "pmap_copy" "pmap_t dst_map" "pmap_t src_map" "vaddr_t dst_addr" \ 80 "vsize_t len" "vaddr_t src_addr" 81.Ft void 82.Fn "pmap_collect" "pmap_t pmap" 83.Ft void 84.Fn "pmap_update" "pmap_t pmap" 85.Ft void 86.Fn "pmap_activate" "struct lwp *l" 87.Ft void 88.Fn "pmap_deactivate" "struct lwp *l" 89.Ft void 90.Fn "pmap_zero_page" "paddr_t pa" 91.Ft void 92.Fn "pmap_copy_page" "paddr_t src" "paddr_t dst" 93.Ft void 94.Fn "pmap_page_protect" "struct vm_page *pg" "vm_prot_t prot" 95.Ft bool 96.Fn "pmap_clear_modify" "struct vm_page *pg" 97.Ft bool 98.Fn "pmap_clear_reference" "struct vm_page *pg" 99.Ft bool 100.Fn "pmap_is_modified" "struct vm_page *pg" 101.Ft bool 102.Fn "pmap_is_referenced" "struct vm_page *pg" 103.Ft paddr_t 104.Fn "pmap_phys_address" "paddr_t cookie" 105.Ft vaddr_t 106.Fn "PMAP_MAP_POOLPAGE" "paddr_t pa" 107.Ft paddr_t 108.Fn "PMAP_UNMAP_POOLPAGE" "vaddr_t va" 109.Ft void 110.Fn "PMAP_PREFER" "vaddr_t hint" "vaddr_t *vap" "vsize_t sz" "int td" 111.Sh DESCRIPTION 112The 113.Nm 114module is the machine-dependent portion of the 115.Nx 116virtual memory system 117.Xr uvm 9 . 118The purpose of the 119.Nm 120module is to manage physical address maps, to program the 121memory management hardware on the system, and perform any 122cache operations necessary to ensure correct operation of 123the virtual memory system. 124The 125.Nm 126module is also responsible for maintaining certain information 127required by 128.Xr uvm 9 . 129.Pp 130In order to cope with hardware architectures that make the 131invalidation of virtual address mappings expensive (e.g., 132TLB invalidations, TLB shootdown operations for multiple 133processors), the 134.Nm 135module is allowed to delay mapping invalidation or protection 136operations until such time as they are actually necessary. 137The functions that are allowed to delay such actions are 138.Fn pmap_enter , 139.Fn pmap_remove , 140.Fn pmap_protect , 141.Fn pmap_kenter_pa , 142and 143.Fn pmap_kremove . 144Callers of these functions must use the 145.Fn pmap_update 146function to notify the 147.Nm 148module that the mappings need to be made correct. 149Since the 150.Nm 151module is provided with information as to which processors are 152using a given physical map, the 153.Nm 154module may use whatever optimizations it has available to reduce 155the expense of virtual-to-physical mapping synchronization. 156.Ss HEADER FILES AND DATA STRUCTURES 157Machine-dependent code must provide the header file 158.Aq Pa machine/pmap.h . 159This file contains the definition of the 160.Dv pmap 161structure: 162.Bd -literal -offset indent 163struct pmap { 164 /* Contents defined by pmap implementation. */ 165}; 166typedef struct pmap *pmap_t; 167.Ed 168.Pp 169This header file may also define other data structures that the 170.Nm 171implementation uses. 172.Pp 173Note that all prototypes for 174.Nm 175interface functions are provided by the header file 176.Aq Pa uvm/uvm_pmap.h . 177It is possible to override this behavior by defining the 178C pre-processor macro 179.Dv PMAP_EXCLUDE_DECLS . 180This may be used to add a layer of indirection to 181.Nm 182API calls, for handling different MMU types in a single 183.Nm 184module, for example. 185If the 186.Dv PMAP_EXCLUDE_DECLS 187macro is defined, 188.Aq Pa machine/pmap.h 189.Em must 190provide function prototypes in a block like so: 191.Bd -literal -offset indent 192#ifdef _KERNEL /* not exposed to user namespace */ 193__BEGIN_DECLS /* make safe for C++ */ 194/* Prototypes go here. */ 195__END_DECLS 196#endif /* _KERNEL */ 197.Ed 198.Pp 199The header file 200.Aq Pa uvm/uvm_pmap.h 201defines a structure for tracking 202.Nm 203statistics (see below). 204This structure is defined as: 205.Bd -literal -offset indent 206struct pmap_statistics { 207 long resident_count; /* number of mapped pages */ 208 long wired_count; /* number of wired pages */ 209}; 210.Ed 211.Ss WIRED MAPPINGS 212The 213.Nm 214module is based on the premise that all information contained 215in the physical maps it manages is redundant. 216That is, physical map information may be 217.Dq forgotten 218by the 219.Nm 220module in the event that it is necessary to do so; it can be rebuilt 221by 222.Xr uvm 9 223by taking a page fault. 224There is one exception to this rule: so-called 225.Dq wired 226mappings may not be forgotten. 227Wired mappings are those for which either no high-level information 228exists with which to rebuild the mapping, or mappings which are needed 229by critical sections of code where taking a page fault is unacceptable. 230Information about which mappings are wired is provided to the 231.Nm 232module when a mapping is established. 233.Ss MODIFIED/REFERENCED INFORMATION 234The 235.Nm 236module is required to keep track of whether or not a page managed 237by the virtual memory system has been referenced or modified. 238This information is used by 239.Xr uvm 9 240to determine what happens to the page when scanned by the 241pagedaemon. 242.Pp 243Many CPUs provide hardware support for tracking 244modified/referenced information. 245However, many CPUs, particularly modern RISC CPUs, do not. 246On CPUs which lack hardware support for modified/referenced tracking, the 247.Nm 248module must emulate it in software. 249There are several strategies for doing this, and the best strategy 250depends on the CPU. 251.Pp 252The 253.Dq referenced 254attribute is used by the pagedaemon to determine if a page is 255.Dq active . 256Active pages are not candidates for re-use in the page replacement algorithm. 257Accurate referenced information is not required for correct operation; if 258supplying referenced information for a page is not feasible, then the 259.Nm 260implementation should always consider the 261.Dq referenced 262attribute to be 263.Dv false . 264.Pp 265The 266.Dq modified 267attribute is used by the pagedaemon to determine if a page needs 268to be cleaned (written to backing store; swap space, a regular file, etc.). 269Accurate modified information 270.Em must 271be provided by the 272.Nm 273module for correct operation of the virtual memory system. 274.Pp 275Note that modified/referenced information is only tracked for 276pages managed by the virtual memory system (i.e., pages for 277which a vm_page structure exists). 278In addition, only 279.Dq managed 280mappings of those pages have modified/referenced tracking. 281Mappings entered with the 282.Fn pmap_enter 283function are 284.Dq managed 285mappings. 286It is possible for 287.Dq unmanaged 288mappings of a page to be created, using the 289.Fn pmap_kenter_pa 290function. 291The use of 292.Dq unmanaged 293mappings should be limited to code which may execute in interrupt context 294(for example, the kernel memory allocator), or to enter mappings for 295physical addresses which are not managed by the virtual memory system. 296.Dq Unmanaged 297mappings may only be entered into the kernel's virtual address space. 298This constraint is placed on the callers of the 299.Fn pmap_kenter_pa 300and 301.Fn pmap_kremove 302functions so that the 303.Nm 304implementation need not block interrupts when manipulating data 305structures or holding locks. 306.Pp 307Also note that the modified/referenced information must be tracked 308on a per-page basis; they are not attributes of a mapping, but attributes 309of a page. 310Therefore, even after all mappings for a given page have 311been removed, the modified/referenced information for that page 312.Em must 313be preserved. 314The only time the modified/referenced attributes may 315be cleared is when the virtual memory system explicitly calls the 316.Fn pmap_clear_modify 317and 318.Fn pmap_clear_reference 319functions. 320These functions must also change any internal state necessary to detect 321the page being modified or referenced again after the modified or 322referenced state is cleared. 323(Prior to 324.Nx 1.6 , 325.Nm 326implementations could get away without this because UVM (and Mach VM 327before that) always called 328.Fn pmap_page_protect 329before clearing the modified or referenced state, but UVM has been changed 330to not do this anymore, so all 331.Nm 332implementations must now handle this.) 333.Ss STATISTICS 334The 335.Nm 336is required to keep statistics as to the number of 337.Dq resident 338pages and the number of 339.Dq wired 340pages. 341.Pp 342A 343.Dq resident 344page is one for which a mapping exists. 345This statistic is used to compute the resident size of a process and 346enforce resource limits. 347Only pages (whether managed by the virtual memory system or not) 348which are mapped into a physical map should be counted in the resident 349count. 350.Pp 351A 352.Dq wired 353page is one for which a wired mapping exists. 354This statistic is used to enforce resource limits. 355.Pp 356Note that it is recommended (though not required) that the 357.Nm 358implementation use the 359.Dv pmap_statistics 360structure in the tracking of 361.Nm 362statistics by placing it inside the 363.Dv pmap 364structure and adjusting the counts when mappings are established, changed, 365or removed. 366This avoids potentially expensive data structure traversals when the 367statistics are queried. 368.Ss REQUIRED FUNCTIONS 369This section describes functions that a 370.Nm 371module must provide to the virtual memory system. 372.Bl -tag -width indent -offset indent 373.It void Fn "pmap_init" "void" 374This function initializes the 375.Nm 376module. 377It is called by 378.Fn uvm_init 379to initialize any data structures that the module needs to 380manage physical maps. 381.It pmap_t Fn "pmap_kernel" "void" 382A machine independent macro which expands to 383.Va kernel_pmap_ptr . 384This variable must be exported by the platform's pmap module and it 385must point to the kernel pmap. 386.It void Fn "pmap_virtual_space" "vaddr_t *vstartp" "vaddr_t *vendp" 387The 388.Fn pmap_virtual_space 389function is called to determine the initial kernel virtual address 390space beginning and end. 391These values are used to create the kernel's virtual memory map. 392The function must set 393.Fa *vstartp 394to the first kernel virtual address that will be managed by 395.Xr uvm 9 , 396and must set 397.Fa *vendp 398to the last kernel virtual address that will be managed by 399.Xr uvm 9 . 400.Pp 401If the 402.Fn pmap_growkernel 403feature is used by a 404.Nm 405implementation, then 406.Fa *vendp 407should be set to the maximum kernel virtual address allowed by the 408implementation. 409If 410.Fn pmap_growkernel 411is not used, then 412.Fa *vendp 413.Em must 414be set to the maximum kernel virtual address that can be mapped with 415the resources currently allocated to map the kernel virtual address 416space. 417.It pmap_t Fn "pmap_create" "void" 418Create a physical map and return it to the caller. 419The reference count on the new map is 1. 420.It void Fn "pmap_destroy" "pmap_t pmap" 421Drop the reference count on the specified physical map. 422If the reference count drops to 0, all resources associated with the 423physical map are released and the physical map destroyed. 424In the case of a drop-to-0, no mappings will exist in the map. 425The 426.Nm 427implementation may assert this. 428.It void Fn "pmap_reference" "pmap_t pmap" 429Increment the reference count on the specified physical map. 430.It long Fn "pmap_resident_count" "pmap_t pmap" 431Query the 432.Dq resident pages 433statistic for 434.Fa pmap . 435.Pp 436Note that this function may be provided as a C pre-processor macro. 437.It long Fn "pmap_wired_count" "pmap_t pmap" 438Query the 439.Dq wired pages 440statistic for 441.Fa pmap . 442.Pp 443Note that this function may be provided as a C pre-processor macro. 444.It int Fn "pmap_enter" "pmap_t pmap" "vaddr_t va" "paddr_t pa" \ 445 "vm_prot_t prot" "int flags" 446Create a mapping in physical map 447.Fa pmap 448for the physical address 449.Fa pa 450at the virtual address 451.Fa va 452with protection specified by bits in 453.Fa prot : 454.Bl -tag -width "VM_PROT_EXECUTE " -offset indent 455.It VM_PROT_READ 456The mapping must allow reading. 457.It VM_PROT_WRITE 458The mapping must allow writing. 459.It VM_PROT_EXECUTE 460The page mapped contains instructions that will be executed by the 461processor. 462.El 463.Pp 464The 465.Fa flags 466argument contains protection bits (the same bits as used in the 467.Fa prot 468argument) indicating the type of access that caused the mapping to 469be created. 470This information may be used to seed modified/referenced 471information for the page being mapped, possibly avoiding redundant faults 472on platforms that track modified/referenced information in software. 473Other information provided by 474.Fa flags : 475.Bl -tag -width "PMAP_CANFAIL " -offset indent 476.It PMAP_WIRED 477The mapping being created is a wired mapping. 478.It PMAP_CANFAIL 479The call to 480.Fn pmap_enter 481is allowed to fail. 482If this flag is 483.Em not 484set, and the 485.Fn pmap_enter 486call is unable to create the mapping, perhaps due to insufficient 487resources, the 488.Nm 489module must panic. 490.El 491.Pp 492The access type provided in the 493.Fa flags 494argument will never exceed the protection specified by 495.Fa prot . 496The 497.Nm 498implementation may assert this. 499Note that on systems that do not provide hardware support for 500tracking modified/referenced information, modified/referenced 501information for the page 502.Em must 503be seeded with the access type provided in 504.Fa flags 505if the 506.Dv PMAP_WIRED 507flag is set. 508This is to prevent a fault for the purpose of tracking 509modified/referenced information from occurring while the system is in 510a critical section where a fault would be unacceptable. 511.Pp 512Note that 513.Fn pmap_enter 514is sometimes called to enter a mapping at a virtual address 515for which a mapping already exists. 516In this situation, the implementation must take whatever action is 517necessary to invalidate the previous mapping before entering the new one. 518.Pp 519Also note that 520.Fn pmap_enter 521is sometimes called to change the protection for a pre-existing 522mapping, or to change the 523.Dq wired 524attribute for a pre-existing mapping. 525.Pp 526The 527.Fn pmap_enter 528function returns 0 on success or an error code indicating the mode 529of failure. 530.It void Fn "pmap_remove" "pmap_t pmap" "vaddr_t sva" "vaddr_t eva" 531Remove mappings from the virtual address range 532.Fa sva 533to 534.Fa eva 535from the specified physical map. 536.It void Fn "pmap_remove_all" "pmap_t pmap" 537This function is a hint to the 538.Nm pmap 539implementation that all entries in 540.Fa pmap 541will be removed before any more entries are entered. 542Following this call, there will be 543.Fn pmap_remove 544calls resulting in every mapping being removed, followed by either 545.Fn pmap_destroy 546or 547.Fn pmap_update . 548No other 549.Nm pmap 550interfaces which take 551.Fa pmap 552as an argument will be called during this process. 553Other interfaces which might need to access 554.Fa pmap 555(such as 556.Fn pmap_page_protect ) 557are permitted during this process. 558.Pp 559The 560.Nm pmap 561implementation is free to either remove all the 562.Nm pmap Ns 's 563mappings immediately in 564.Fn pmap_remove_all , 565or to use the knowledge of the upcoming 566.Fn pmap_remove 567calls to optimize the removals (or to just ignore this call). 568.Pp 569.It void Fn "pmap_protect" "pmap_t pmap" "vaddr_t sva" "vaddr_t eva" \ 570 "vm_prot_t prot" 571Set the protection of the mappings in the virtual address range 572.Fa sva 573to 574.Fa eva 575in the specified physical map. 576.It void Fn "pmap_unwire" "pmap_t pmap" "vaddr_t va" 577Clear the 578.Dq wired 579attribute on the mapping for virtual address 580.Fa va . 581.It bool Fn "pmap_extract" "pmap_t pmap" "vaddr_t va" "paddr_t *pap" 582This function extracts a mapping from the specified physical map. 583It serves two purposes: to determine if a mapping exists for the specified 584virtual address, and to determine what physical address is mapped at the 585specified virtual address. 586The 587.Fn pmap_extract 588should return the physical address for any kernel-accessible address, 589including KSEG-style direct-mapped kernel addresses. 590.Pp 591The 592.Fn pmap_extract 593function returns 594.Dv false 595if a mapping for 596.Fa va 597does not exist. 598Otherwise, it returns 599.Dv true 600and places the physical address mapped at 601.Fa va 602into 603.Fa *pap 604if the 605.Fa pap 606argument is non-NULL. 607.It void Fn "pmap_kenter_pa" "vaddr_t va" "paddr_t pa" "vm_prot_t prot" 608Enter an 609.Dq unmanaged 610mapping for physical address 611.Fa pa 612at virtual address 613.Fa va 614with protection 615.Fa prot 616into the kernel physical map. 617Mappings of this type are always 618.Dq wired , 619and are unaffected by routines that alter the protection of pages 620(such as 621.Fn pmap_page_protect ) . 622Such mappings are also not included in the gathering of modified/referenced 623information about a page. 624Mappings entered with 625.Fn pmap_kenter_pa 626by machine-independent code 627.Em must not 628have execute permission, as the 629data structures required to track execute permission of a page may not 630be available to 631.Fn pmap_kenter_pa . 632Machine-independent code is not allowed to enter a mapping with 633.Fn pmap_kenter_pa 634at a virtual address for which a valid mapping already exists. 635Mappings created with 636.Fn pmap_kenter_pa 637may be removed only with a call to 638.Fn pmap_kremove . 639.Pp 640Note that 641.Fn pmap_kenter_pa 642must be safe for use in interrupt context. 643.Fn splvm 644blocks interrupts that might cause 645.Fn pmap_kenter_pa 646to be called. 647.It void Fn "pmap_kremove" "vaddr_t va" "vsize_t size" 648Remove all mappings starting at virtual address 649.Fa va 650for 651.Fa size 652bytes from the kernel physical map. 653All mappings that are removed must be the 654.Dq unmanaged 655type created with 656.Fn pmap_kenter_pa . 657The implementation may assert this. 658.It void Fn "pmap_copy" "pmap_t dst_map" "pmap_t src_map" "vaddr_t dst_addr" \ 659 "vsize_t len" "vaddr_t src_addr" 660This function copies the mappings starting at 661.Fa src_addr 662in 663.Fa src_map 664for 665.Fa len 666bytes into 667.Fa dst_map 668starting at 669.Fa dst_addr . 670.Pp 671Note that while this function is required to be provided by a 672.Nm 673implementation, it is not actually required to do anything. 674.Fn pmap_copy 675is merely advisory (it is used in the 676.Xr fork 2 677path to 678.Dq pre-fault 679the child's address space). 680.It void Fn "pmap_collect" "pmap_t pmap" 681This function is called just before a process is swapped out to 682allow the 683.Nm 684module to release resources used to map the process's address space. 685The implementation may choose to remove physical mappings in order 686to free for example page tables back to the system. 687Note, however, that wired mappings must 688.Em not 689be removed when 690.Fn pmap_collect 691is called. 692.Pp 693Note that while this function is required to be provided by a 694.Nm 695implementation, it is not actually required to do anything. 696.Fn pmap_collect 697is merely advisory. 698It is recommended, however, that 699.Fn pmap_collect 700be fully implemented by a 701.Nm 702implementation. 703.It void Fn "pmap_update" "pmap_t pmap" 704This function is used to inform the 705.Nm 706module that all physical mappings, for the specified pmap, must now be 707correct. 708That is, all delayed virtual-to-physical mappings updates (such as TLB 709invalidation or address space identifier updates) must be completed. 710This routine must be used after calls to 711.Fn pmap_enter , 712.Fn pmap_remove , 713.Fn pmap_protect , 714.Fn pmap_kenter_pa , 715and 716.Fn pmap_kremove 717in order to ensure correct operation of the virtual memory system. 718.Pp 719If a 720.Nm 721implementation does not delay virtual-to-physical mapping updates, 722.Fn pmap_update 723has no operation. 724In this case, the call may be deleted using a C pre-processor macro in 725.Aq Pa machine/pmap.h . 726.It void Fn "pmap_activate" "struct lwp *l" 727Activate the physical map used by the process behind lwp 728.Fa l . 729This is called by the virtual memory system when the 730virtual memory context for a process is changed, and is also 731often used by machine-dependent context switch code to program 732the memory management hardware with the process's page table 733base, etc. 734Note that 735.Fn pmap_activate 736may not always be called when 737.Fa l 738is the current lwp. 739.Fn pmap_activate 740must be able to handle this scenario. 741.It void Fn "pmap_deactivate" "struct lwp *l" 742Deactivate the physical map used by the process behind lwp 743.Fa l . 744It is generally used in conjunction with 745.Fn pmap_activate . 746Like 747.Fn pmap_activate , 748.Fn pmap_deactivate 749may not always be called when 750.Fa l 751is the current lwp. 752.It void Fn "pmap_zero_page" "paddr_t pa" 753Zero the PAGE_SIZE sized region starting at physical address 754.Fa pa . 755The 756.Nm 757implementation must take whatever steps are necessary to map the 758page to a kernel-accessible address and zero the page. 759It is suggested that implementations use an optimized zeroing algorithm, 760as the performance of this function directly impacts page fault performance. 761The implementation may assume that the region is 762PAGE_SIZE aligned and exactly PAGE_SIZE bytes in length. 763.Pp 764Note that the cache configuration of the platform should also be 765considered in the implementation of 766.Fn pmap_zero_page . 767For example, on systems with a physically-addressed cache, the cache 768load caused by zeroing the page will not be wasted, as the zeroing is 769usually done on-demand. 770However, on systems with a virtually-addressed cached, the cache load 771caused by zeroing the page 772.Em will 773be wasted, as the page will be mapped at a virtual address which is 774different from that used to zero the page. 775In the virtually-addressed cache case, care should also be taken to 776avoid cache alias problems. 777.It void Fn "pmap_copy_page" "paddr_t src" "paddr_t dst" 778Copy the PAGE_SIZE sized region starting at physical address 779.Fa src 780to the same sized region starting at physical address 781.Fa dst . 782The 783.Nm 784implementation must take whatever steps are necessary to map the 785source and destination pages to a kernel-accessible address and 786perform the copy. 787It is suggested that implementations use an optimized copy algorithm, 788as the performance of this function directly impacts page fault performance. 789The implementation may assume that both regions are PAGE_SIZE aligned 790and exactly PAGE_SIZE bytes in length. 791.Pp 792The same cache considerations that apply to 793.Fn pmap_zero_page 794apply to 795.Fn pmap_copy_page . 796.It void Fn "pmap_page_protect" "struct vm_page *pg" "vm_prot_t prot" 797Lower the permissions for all mappings of the page 798.Fa pg 799to 800.Fa prot . 801This function is used by the virtual memory system to implement 802copy-on-write (called with VM_PROT_READ set in 803.Fa prot ) 804and to revoke all mappings when cleaning a page (called with 805no bits set in 806.Fa prot ) . 807Access permissions must never be added to a page as a result of 808this call. 809.It bool Fn "pmap_clear_modify" "struct vm_page *pg" 810Clear the 811.Dq modified 812attribute on the page 813.Fa pg . 814.Pp 815The 816.Fn pmap_clear_modify 817function returns 818.Dv true 819or 820.Dv false 821indicating whether or not the 822.Dq modified 823attribute was set on the page before it was cleared. 824.Pp 825Note that this function may be provided as a C pre-processor macro. 826.It bool Fn "pmap_clear_reference" "struct vm_page *pg" 827Clear the 828.Dq referenced 829attribute on the page 830.Fa pg . 831.Pp 832The 833.Fn pmap_clear_reference 834function returns 835.Dv true 836or 837.Dv false 838indicating whether or not the 839.Dq referenced 840attribute was set on the page before it was cleared. 841.Pp 842Note that this function may be provided as a C pre-processor macro. 843.It bool Fn "pmap_is_modified" "struct vm_page *pg" 844Test whether or not the 845.Dq modified 846attribute is set on page 847.Fa pg . 848.Pp 849Note that this function may be provided as a C pre-processor macro. 850.It bool Fn "pmap_is_referenced" "struct vm_page *pg" 851Test whether or not the 852.Dq referenced 853attribute is set on page 854.Fa pg . 855.Pp 856Note that this function may be provided as a C pre-processor macro. 857.It paddr_t Fn "pmap_phys_address" "paddr_t cookie" 858Convert a cookie returned by a device 859.Fn mmap 860function into a physical address. 861This function is provided to accommodate systems which have physical 862address spaces larger than can be directly addressed by the platform's 863.Fa paddr_t 864type. 865The existence of this function is highly dubious, and it is 866expected that this function will be removed from the 867.Nm pmap 868API in a future release of 869.Nx . 870.Pp 871Note that this function may be provided as a C pre-processor macro. 872.El 873.Ss OPTIONAL FUNCTIONS 874This section describes several optional functions in the 875.Nm 876API. 877.Bl -tag -width indent -offset indent 878.It vaddr_t Fn "pmap_steal_memory" "vsize_t size" "vaddr_t *vstartp" \ 879 "vaddr_t *vendp" 880This function is a bootstrap memory allocator, which may be provided 881as an alternative to the bootstrap memory allocator used within 882.Xr uvm 9 883itself. 884It is particularly useful on systems which provide for example a direct-mapped 885memory segment. 886This function works by stealing pages from the (to be) managed memory 887pool, which has already been provided to 888.Xr uvm 9 889in the vm_physmem[] array. 890The pages are then mapped, or otherwise made accessible to the kernel, 891in a machine-dependent way. 892The memory must be zeroed by 893.Fn pmap_steal_memory . 894Note that memory allocated with 895.Fn pmap_steal_memory 896will never be freed, and mappings made by 897.Fn pmap_steal_memory 898must never be 899.Dq forgotten . 900.Pp 901Note that 902.Fn pmap_steal_memory 903should not be used as a general-purpose early-startup memory 904allocation routine. 905It is intended to be used only by the 906.Fn uvm_pageboot_alloc 907routine and its supporting routines. 908If you need to allocate memory before the virtual memory system is 909initialized, use 910.Fn uvm_pageboot_alloc . 911See 912.Xr uvm 9 913for more information. 914.Pp 915The 916.Fn pmap_steal_memory 917function returns the kernel-accessible address of the allocated memory. 918If no memory can be allocated, or if allocated memory cannot be mapped, 919the function must panic. 920.Pp 921If the 922.Fn pmap_steal_memory 923function uses address space from the range provided to 924.Xr uvm 9 925by the 926.Fn pmap_virtual_space 927call, then 928.Fn pmap_steal_memory 929must adjust 930.Fa *vstartp 931and 932.Fa *vendp 933upon return. 934.Pp 935The 936.Fn pmap_steal_memory 937function is enabled by defining the C pre-processor macro 938.Dv PMAP_STEAL_MEMORY 939in 940.Aq Pa machine/pmap.h . 941.It vaddr_t Fn "pmap_growkernel" "vaddr_t maxkvaddr" 942Management of the kernel virtual address space is complicated by the 943fact that it is not always safe to wait for resources with which to 944map a kernel virtual address. 945However, it is not always desirable to pre-allocate all resources 946necessary to map the entire kernel virtual address space. 947.Pp 948The 949.Fn pmap_growkernel 950interface is designed to help alleviate this problem. 951The virtual memory startup code may choose to allocate an initial set 952of mapping resources (e.g., page tables) and set an internal variable 953indicating how much kernel virtual address space can be mapped using 954those initial resources. 955Then, when the virtual memory system wishes to map something 956at an address beyond that initial limit, it calls 957.Fn pmap_growkernel 958to pre-allocate more sources with which to create the mapping. 959Note that once additional kernel virtual address space mapping resources 960have been allocated, they should not be freed; it is likely they will 961be needed again. 962.Pp 963The 964.Fn pmap_growkernel 965function returns the new maximum kernel virtual address that can be mapped 966with the resources it has available. 967If new resources cannot be allocated, 968.Fn pmap_growkernel 969must panic. 970.Pp 971The 972.Fn pmap_growkernel 973function is enabled by defining the C pre-processor macro 974.Dv PMAP_GROWKERNEL 975in 976.Aq Pa machine/pmap.h . 977.It void Fn "pmap_fork" "pmap_t src_map" "pmap_t dst_map" 978Some 979.Nm 980implementations may need to keep track of other information not 981directly related to the virtual address space. 982For example, on the i386 port, the Local Descriptor Table state of a 983process is associated with the pmap (this is due to the fact that 984applications manipulate the Local Descriptor Table directly expect it 985to be logically associated with the virtual memory state of the process). 986.Pp 987The 988.Fn pmap_fork 989function is provided as a way to associate information from 990.Fa src_map 991with 992.Fa dst_map 993when a 994.Dv vmspace 995is forked. 996.Fn pmap_fork 997is called from 998.Fn uvmspace_fork . 999.Pp 1000The 1001.Fn pmap_fork 1002function is enabled by defining the C pre-processor macro 1003.Dv PMAP_FORK 1004in 1005.Aq Pa machine/pmap.h . 1006.It vaddr_t Fn "PMAP_MAP_POOLPAGE" "paddr_t pa" 1007This function is used by the 1008.Xr pool 9 1009memory pool manager. 1010Pools allocate backing pages one at a time. 1011This is provided as a means to use hardware features such as a 1012direct-mapped memory segment to map the pages used by the 1013.Xr pool 9 1014allocator. 1015This can lead to better performance by e.g. reducing TLB contention. 1016.Pp 1017.Fn PMAP_MAP_POOLPAGE 1018returns the kernel-accessible address of the page being mapped. 1019It must always succeed. 1020.Pp 1021The use of 1022.Fn PMAP_MAP_POOLPAGE 1023is enabled by defining it as a C pre-processor macro in 1024.Aq Pa machine/pmap.h . 1025If 1026.Fn PMAP_MAP_POOLPAGE 1027is defined, 1028.Fn PMAP_UNMAP_POOLPAGE 1029must also be defined. 1030.Pp 1031The following is an example of how to define 1032.Fn PMAP_MAP_POOLPAGE : 1033.Bd -literal -offset indent 1034#define PMAP_MAP_POOLPAGE(pa) MIPS_PHYS_TO_KSEG0((pa)) 1035.Ed 1036.Pp 1037This takes the physical address of a page and returns the KSEG0 1038address of that page on a MIPS processor. 1039.It paddr_t Fn "PMAP_UNMAP_POOLPAGE" "vaddr_t va" 1040This function is the inverse of 1041.Fn PMAP_MAP_POOLPAGE . 1042.Pp 1043.Fn PMAP_UNMAP_POOLPAGE 1044returns the physical address of the page corresponding to the 1045provided kernel-accessible address. 1046.Pp 1047The use of 1048.Fn PMAP_UNMAP_POOLPAGE 1049is enabled by defining it as a C pre-processor macro in 1050.Aq Pa machine/pmap.h . 1051If 1052.Fn PMAP_UNMAP_POOLPAGE 1053is defined, 1054.Fn PMAP_MAP_POOLPAGE 1055must also be defined. 1056.Pp 1057The following is an example of how to define 1058.Fn PMAP_UNMAP_POOLPAGE : 1059.Bd -literal -offset indent 1060#define PMAP_UNMAP_POOLPAGE(pa) MIPS_KSEG0_TO_PHYS((va)) 1061.Ed 1062.Pp 1063This takes the KSEG0 address of a previously-mapped pool page 1064and returns the physical address of that page on a MIPS processor. 1065.It void Fn "PMAP_PREFER" "vaddr_t hint" "vaddr_t *vap" "vsize_t sz" "int td" 1066This function is used by 1067.Xr uvm_map 9 1068to adjust a virtual address being allocated in order to avoid 1069cache alias problems. 1070If necessary, the virtual address pointed by 1071.Fa vap 1072will be advanced. 1073.Fa hint 1074is an object offset which will be mapped into the resulting virtual address, and 1075.Fa sz 1076is size of the object. 1077.Fa td 1078indicates if the machine dependent pmap uses the topdown VM. 1079.Pp 1080The use of 1081.Fn PMAP_PREFER 1082is enabled by defining it as a C pre-processor macro in 1083.Aq Pa machine/pmap.h . 1084.Pp 1085.It void Fn "pmap_procwr" "struct proc *p" "vaddr_t va" "vsize_t size" 1086Synchronize CPU instruction caches of the specified range. 1087The address space is designated by 1088.Fa p . 1089This function is typically used to flush instruction caches 1090after code modification. 1091.Pp 1092The use of 1093.Fn pmap_procwr 1094is enabled by defining a C pre-processor macro 1095.Dv PMAP_NEED_PROCWR 1096in 1097.Aq Pa machine/pmap.h . 1098.El 1099.Sh SEE ALSO 1100.Xr uvm 9 1101.Sh HISTORY 1102The 1103.Nm 1104module was originally part of the design of the virtual memory system 1105in the Mach Operating System. 1106The goal was to provide a clean separation between the machine-independent 1107and the machine-dependent portions of the virtual memory system, in 1108stark contrast to the original 1109.Bx 3 1110virtual memory system, which was specific to the VAX. 1111.Pp 1112Between 1113.Bx 4.3 1114and 1115.Bx 4.4 , 1116the Mach virtual memory system, including the 1117.Nm 1118API, was ported to 1119.Bx 1120and included in the 1121.Bx 4.4 1122release. 1123.Pp 1124.Nx 1125inherited the 1126.Bx 1127version of the Mach virtual memory system. 1128.Nx 1.4 1129was the first 1130.Nx 1131release with the new 1132.Xr uvm 9 1133virtual memory system, which included several changes to the 1134.Nm 1135API. 1136Since the introduction of 1137.Xr uvm 9 , 1138the 1139.Nm 1140API has evolved further. 1141.Sh AUTHORS 1142The original Mach VAX 1143.Nm 1144module was written by 1145.An Avadis Tevanian, Jr. 1146and 1147.An Michael Wayne Young . 1148.Pp 1149.An Mike Hibler 1150did the integration of the Mach virtual memory system into 1151.Bx 4.4 1152and implemented a 1153.Nm 1154module for the Motorola 68020+68851/68030/68040. 1155.Pp 1156The 1157.Nm 1158API as it exists in 1159.Nx 1160is derived from 1161.Bx 4.4 , 1162and has been modified by 1163.An Chuck Cranor , 1164.An Charles M. Hannum , 1165.An Chuck Silvers , 1166.An Wolfgang Solfrank , 1167.An Bill Sommerfeld , 1168and 1169.An Jason R. Thorpe . 1170.Pp 1171The author of this document is 1172.An Jason R. Thorpe 1173.Aq thorpej@NetBSD.org . 1174.Sh BUGS 1175The use and definition of 1176.Fn pmap_activate 1177and 1178.Fn pmap_deactivate 1179needs to be reexamined. 1180.Pp 1181The use of 1182.Fn pmap_copy 1183needs to be reexamined. 1184Empirical evidence suggests that performance of the system suffers when 1185.Fn pmap_copy 1186actually performs its defined function. 1187This is largely due to the fact that the copy of the virtual-to-physical 1188mappings is wasted if the process calls 1189.Xr execve 2 1190after 1191.Xr fork 2 . 1192For this reason, it is recommended that 1193.Nm 1194implementations leave the body of the 1195.Fn pmap_copy 1196function empty for now. 1197