1.\" $NetBSD: pmap.9,v 1.36 2008/04/30 13:10:58 martin 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 25, 2007 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" 382Return a pointer to the 383.Dv pmap 384structure that maps the kernel virtual address space. 385.Pp 386Note that this function may be provided as a C pre-processor macro. 387.It void Fn "pmap_virtual_space" "vaddr_t *vstartp" "vaddr_t *vendp" 388The 389.Fn pmap_virtual_space 390function is called to determine the initial kernel virtual address 391space beginning and end. 392These values are used to create the kernel's virtual memory map. 393The function must set 394.Fa *vstartp 395to the first kernel virtual address that will be managed by 396.Xr uvm 9 , 397and must set 398.Fa *vendp 399to the last kernel virtual address that will be managed by 400.Xr uvm 9 . 401.Pp 402If the 403.Fn pmap_growkernel 404feature is used by a 405.Nm 406implementation, then 407.Fa *vendp 408should be set to the maximum kernel virtual address allowed by the 409implementation. 410If 411.Fn pmap_growkernel 412is not used, then 413.Fa *vendp 414.Em must 415be set to the maximum kernel virtual address that can be mapped with 416the resources currently allocated to map the kernel virtual address 417space. 418.It pmap_t Fn "pmap_create" "void" 419Create a physical map and return it to the caller. 420The reference count on the new map is 1. 421.It void Fn "pmap_destroy" "pmap_t pmap" 422Drop the reference count on the specified physical map. 423If the reference count drops to 0, all resources associated with the 424physical map are released and the physical map destroyed. 425In the case of a drop-to-0, no mappings will exist in the map. 426The 427.Nm 428implementation may assert this. 429.It void Fn "pmap_reference" "pmap_t pmap" 430Increment the reference count on the specified physical map. 431.It long Fn "pmap_resident_count" "pmap_t pmap" 432Query the 433.Dq resident pages 434statistic for 435.Fa pmap . 436.Pp 437Note that this function may be provided as a C pre-processor macro. 438.It long Fn "pmap_wired_count" "pmap_t pmap" 439Query the 440.Dq wired pages 441statistic for 442.Fa pmap . 443.Pp 444Note that this function may be provided as a C pre-processor macro. 445.It int Fn "pmap_enter" "pmap_t pmap" "vaddr_t va" "paddr_t pa" \ 446 "vm_prot_t prot" "int flags" 447Create a mapping in physical map 448.Fa pmap 449for the physical address 450.Fa pa 451at the virtual address 452.Fa va 453with protection specified by bits in 454.Fa prot : 455.Bl -tag -width "VM_PROT_EXECUTE " -offset indent 456.It VM_PROT_READ 457The mapping must allow reading. 458.It VM_PROT_WRITE 459The mapping must allow writing. 460.It VM_PROT_EXECUTE 461The page mapped contains instructions that will be executed by the 462processor. 463.El 464.Pp 465The 466.Fa flags 467argument contains protection bits (the same bits as used in the 468.Fa prot 469argument) indicating the type of access that caused the mapping to 470be created. 471This information may be used to seed modified/referenced 472information for the page being mapped, possibly avoiding redundant faults 473on platforms that track modified/referenced information in software. 474Other information provided by 475.Fa flags : 476.Bl -tag -width "PMAP_CANFAIL " -offset indent 477.It PMAP_WIRED 478The mapping being created is a wired mapping. 479.It PMAP_CANFAIL 480The call to 481.Fn pmap_enter 482is allowed to fail. 483If this flag is 484.Em not 485set, and the 486.Fn pmap_enter 487call is unable to create the mapping, perhaps due to insufficient 488resources, the 489.Nm 490module must panic. 491.El 492.Pp 493The access type provided in the 494.Fa flags 495argument will never exceed the protection specified by 496.Fa prot . 497The 498.Nm 499implementation may assert this. 500Note that on systems that do not provide hardware support for 501tracking modified/referenced information, modified/referenced 502information for the page 503.Em must 504be seeded with the access type provided in 505.Fa flags 506if the 507.Dv PMAP_WIRED 508flag is set. 509This is to prevent a fault for the purpose of tracking 510modified/referenced information from occurring while the system is in 511a critical section where a fault would be unacceptable. 512.Pp 513Note that 514.Fn pmap_enter 515is sometimes called to enter a mapping at a virtual address 516for which a mapping already exists. 517In this situation, the implementation must take whatever action is 518necessary to invalidate the previous mapping before entering the new one. 519.Pp 520Also note that 521.Fn pmap_enter 522is sometimes called to change the protection for a pre-existing 523mapping, or to change the 524.Dq wired 525attribute for a pre-existing mapping. 526.Pp 527The 528.Fn pmap_enter 529function returns 0 on success or an error code indicating the mode 530of failure. 531.It void Fn "pmap_remove" "pmap_t pmap" "vaddr_t sva" "vaddr_t eva" 532Remove mappings from the virtual address range 533.Fa sva 534to 535.Fa eva 536from the specified physical map. 537.It void Fn "pmap_remove_all" "pmap_t pmap" 538This function is a hint to the 539.Nm pmap 540implementation that all entries in 541.Fa pmap 542will be removed before any more entries are entered. 543Following this call, there will be 544.Fn pmap_remove 545calls resulting in every mapping being removed, followed by either 546.Fn pmap_destroy 547or 548.Fn pmap_update . 549No other 550.Nm pmap 551interfaces which take 552.Fa pmap 553as an argument will be called during this process. 554Other interfaces which might need to access 555.Fa pmap 556(such as 557.Fn pmap_page_protect ) 558are permitted during this process. 559.Pp 560The 561.Nm pmap 562implementation is free to either remove all the 563.Nm pmap Ns 's 564mappings immediately in 565.Fn pmap_remove_all , 566or to use the knowledge of the upcoming 567.Fn pmap_remove 568calls to optimize the removals (or to just ignore this call). 569.Pp 570.It void Fn "pmap_protect" "pmap_t pmap" "vaddr_t sva" "vaddr_t eva" \ 571 "vm_prot_t prot" 572Set the protection of the mappings in the virtual address range 573.Fa sva 574to 575.Fa eva 576in the specified physical map. 577.It void Fn "pmap_unwire" "pmap_t pmap" "vaddr_t va" 578Clear the 579.Dq wired 580attribute on the mapping for virtual address 581.Fa va . 582.It bool Fn "pmap_extract" "pmap_t pmap" "vaddr_t va" "paddr_t *pap" 583This function extracts a mapping from the specified physical map. 584It serves two purposes: to determine if a mapping exists for the specified 585virtual address, and to determine what physical address is mapped at the 586specified virtual address. 587The 588.Fn pmap_extract 589should return the physical address for any kernel-accessible address, 590including KSEG-style direct-mapped kernel addresses. 591.Pp 592The 593.Fn pmap_extract 594function returns 595.Dv false 596if a mapping for 597.Fa va 598does not exist. 599Otherwise, it returns 600.Dv true 601and places the physical address mapped at 602.Fa va 603into 604.Fa *pap 605if the 606.Fa pap 607argument is non-NULL. 608.It void Fn "pmap_kenter_pa" "vaddr_t va" "paddr_t pa" "vm_prot_t prot" 609Enter an 610.Dq unmanaged 611mapping for physical address 612.Fa pa 613at virtual address 614.Fa va 615with protection 616.Fa prot 617into the kernel physical map. 618Mappings of this type are always 619.Dq wired , 620and are unaffected by routines that alter the protection of pages 621(such as 622.Fn pmap_page_protect ) . 623Such mappings are also not included in the gathering of modified/referenced 624information about a page. 625Mappings entered with 626.Fn pmap_kenter_pa 627by machine-independent code 628.Em must not 629have execute permission, as the 630data structures required to track execute permission of a page may not 631be available to 632.Fn pmap_kenter_pa . 633Machine-independent code is not allowed to enter a mapping with 634.Fn pmap_kenter_pa 635at a virtual address for which a valid mapping already exists. 636Mappings created with 637.Fn pmap_kenter_pa 638may be removed only with a call to 639.Fn pmap_kremove . 640.Pp 641Note that 642.Fn pmap_kenter_pa 643must be safe for use in interrupt context. 644.Fn splvm 645blocks interrupts that might cause 646.Fn pmap_kenter_pa 647to be called. 648.It void Fn "pmap_kremove" "vaddr_t va" "vsize_t size" 649Remove all mappings starting at virtual address 650.Fa va 651for 652.Fa size 653bytes from the kernel physical map. 654All mappings that are removed must be the 655.Dq unmanaged 656type created with 657.Fn pmap_kenter_pa . 658The implementation may assert this. 659.It void Fn "pmap_copy" "pmap_t dst_map" "pmap_t src_map" "vaddr_t dst_addr" \ 660 "vsize_t len" "vaddr_t src_addr" 661This function copies the mappings starting at 662.Fa src_addr 663in 664.Fa src_map 665for 666.Fa len 667bytes into 668.Fa dst_map 669starting at 670.Fa dst_addr . 671.Pp 672Note that while this function is required to be provided by a 673.Nm 674implementation, it is not actually required to do anything. 675.Fn pmap_copy 676is merely advisory (it is used in the 677.Xr fork 2 678path to 679.Dq pre-fault 680the child's address space). 681.It void Fn "pmap_collect" "pmap_t pmap" 682This function is called just before a process is swapped out to 683allow the 684.Nm 685module to release resources used to map the process's address space. 686The implementation may choose to remove physical mappings in order 687to free for example page tables back to the system. 688Note, however, that wired mappings must 689.Em not 690be removed when 691.Fn pmap_collect 692is called. 693.Pp 694Note that while this function is required to be provided by a 695.Nm 696implementation, it is not actually required to do anything. 697.Fn pmap_collect 698is merely advisory. 699It is recommended, however, that 700.Fn pmap_collect 701be fully implemented by a 702.Nm 703implementation. 704.It void Fn "pmap_update" "pmap_t pmap" 705This function is used to inform the 706.Nm 707module that all physical mappings, for the specified pmap, must now be 708correct. 709That is, all delayed virtual-to-physical mappings updates (such as TLB 710invalidation or address space identifier updates) must be completed. 711This routine must be used after calls to 712.Fn pmap_enter , 713.Fn pmap_remove , 714.Fn pmap_protect , 715.Fn pmap_kenter_pa , 716and 717.Fn pmap_kremove 718in order to ensure correct operation of the virtual memory system. 719.Pp 720If a 721.Nm 722implementation does not delay virtual-to-physical mapping updates, 723.Fn pmap_update 724has no operation. 725In this case, the call may be deleted using a C pre-processor macro in 726.Aq Pa machine/pmap.h . 727.It void Fn "pmap_activate" "struct lwp *l" 728Activate the physical map used by the process behind lwp 729.Fa l . 730This is called by the virtual memory system when the 731virtual memory context for a process is changed, and is also 732often used by machine-dependent context switch code to program 733the memory management hardware with the process's page table 734base, etc. 735Note that 736.Fn pmap_activate 737may not always be called when 738.Fa l 739is the current lwp. 740.Fn pmap_activate 741must be able to handle this scenario. 742.It void Fn "pmap_deactivate" "struct lwp *l" 743Deactivate the physical map used by the process behind lwp 744.Fa l . 745It is generally used in conjunction with 746.Fn pmap_activate . 747Like 748.Fn pmap_activate , 749.Fn pmap_deactivate 750may not always be called when 751.Fa l 752is the current lwp. 753.It void Fn "pmap_zero_page" "paddr_t pa" 754Zero the PAGE_SIZE sized region starting at physical address 755.Fa pa . 756The 757.Nm 758implementation must take whatever steps are necessary to map the 759page to a kernel-accessible address and zero the page. 760It is suggested that implementations use an optimized zeroing algorithm, 761as the performance of this function directly impacts page fault performance. 762The implementation may assume that the region is 763PAGE_SIZE aligned and exactly PAGE_SIZE bytes in length. 764.Pp 765Note that the cache configuration of the platform should also be 766considered in the implementation of 767.Fn pmap_zero_page . 768For example, on systems with a physically-addressed cache, the cache 769load caused by zeroing the page will not be wasted, as the zeroing is 770usually done on-demand. 771However, on systems with a virtually-addressed cached, the cache load 772caused by zeroing the page 773.Em will 774be wasted, as the page will be mapped at a virtual address which is 775different from that used to zero the page. 776In the virtually-addressed cache case, care should also be taken to 777avoid cache alias problems. 778.It void Fn "pmap_copy_page" "paddr_t src" "paddr_t dst" 779Copy the PAGE_SIZE sized region starting at physical address 780.Fa src 781to the same sized region starting at physical address 782.Fa dst . 783The 784.Nm 785implementation must take whatever steps are necessary to map the 786source and destination pages to a kernel-accessible address and 787perform the copy. 788It is suggested that implementations use an optimized copy algorithm, 789as the performance of this function directly impacts page fault performance. 790The implementation may assume that both regions are PAGE_SIZE aligned 791and exactly PAGE_SIZE bytes in length. 792.Pp 793The same cache considerations that apply to 794.Fn pmap_zero_page 795apply to 796.Fn pmap_copy_page . 797.It void Fn "pmap_page_protect" "struct vm_page *pg" "vm_prot_t prot" 798Lower the permissions for all mappings of the page 799.Fa pg 800to 801.Fa prot . 802This function is used by the virtual memory system to implement 803copy-on-write (called with VM_PROT_READ set in 804.Fa prot ) 805and to revoke all mappings when cleaning a page (called with 806no bits set in 807.Fa prot ) . 808Access permissions must never be added to a page as a result of 809this call. 810.It bool Fn "pmap_clear_modify" "struct vm_page *pg" 811Clear the 812.Dq modified 813attribute on the page 814.Fa pg . 815.Pp 816The 817.Fn pmap_clear_modify 818function returns 819.Dv true 820or 821.Dv false 822indicating whether or not the 823.Dq modified 824attribute was set on the page before it was cleared. 825.Pp 826Note that this function may be provided as a C pre-processor macro. 827.It bool Fn "pmap_clear_reference" "struct vm_page *pg" 828Clear the 829.Dq referenced 830attribute on the page 831.Fa pg . 832.Pp 833The 834.Fn pmap_clear_reference 835function returns 836.Dv true 837or 838.Dv false 839indicating whether or not the 840.Dq referenced 841attribute was set on the page before it was cleared. 842.Pp 843Note that this function may be provided as a C pre-processor macro. 844.It bool Fn "pmap_is_modified" "struct vm_page *pg" 845Test whether or not the 846.Dq modified 847attribute is set on page 848.Fa pg . 849.Pp 850Note that this function may be provided as a C pre-processor macro. 851.It bool Fn "pmap_is_referenced" "struct vm_page *pg" 852Test whether or not the 853.Dq referenced 854attribute is set on page 855.Fa pg . 856.Pp 857Note that this function may be provided as a C pre-processor macro. 858.It paddr_t Fn "pmap_phys_address" "paddr_t cookie" 859Convert a cookie returned by a device 860.Fn mmap 861function into a physical address. 862This function is provided to accommodate systems which have physical 863address spaces larger than can be directly addressed by the platform's 864.Fa paddr_t 865type. 866The existence of this function is highly dubious, and it is 867expected that this function will be removed from the 868.Nm pmap 869API in a future release of 870.Nx . 871.Pp 872Note that this function may be provided as a C pre-processor macro. 873.El 874.Ss OPTIONAL FUNCTIONS 875This section describes several optional functions in the 876.Nm 877API. 878.Bl -tag -width indent -offset indent 879.It vaddr_t Fn "pmap_steal_memory" "vsize_t size" "vaddr_t *vstartp" \ 880 "vaddr_t *vendp" 881This function is a bootstrap memory allocator, which may be provided 882as an alternative to the bootstrap memory allocator used within 883.Xr uvm 9 884itself. 885It is particularly useful on systems which provide for example a direct-mapped 886memory segment. 887This function works by stealing pages from the (to be) managed memory 888pool, which has already been provided to 889.Xr uvm 9 890in the vm_physmem[] array. 891The pages are then mapped, or otherwise made accessible to the kernel, 892in a machine-dependent way. 893The memory must be zeroed by 894.Fn pmap_steal_memory . 895Note that memory allocated with 896.Fn pmap_steal_memory 897will never be freed, and mappings made by 898.Fn pmap_steal_memory 899must never be 900.Dq forgotten . 901.Pp 902Note that 903.Fn pmap_steal_memory 904should not be used as a general-purpose early-startup memory 905allocation routine. 906It is intended to be used only by the 907.Fn uvm_pageboot_alloc 908routine and its supporting routines. 909If you need to allocate memory before the virtual memory system is 910initialized, use 911.Fn uvm_pageboot_alloc . 912See 913.Xr uvm 9 914for more information. 915.Pp 916The 917.Fn pmap_steal_memory 918function returns the kernel-accessible address of the allocated memory. 919If no memory can be allocated, or if allocated memory cannot be mapped, 920the function must panic. 921.Pp 922If the 923.Fn pmap_steal_memory 924function uses address space from the range provided to 925.Xr uvm 9 926by the 927.Fn pmap_virtual_space 928call, then 929.Fn pmap_steal_memory 930must adjust 931.Fa *vstartp 932and 933.Fa *vendp 934upon return. 935.Pp 936The 937.Fn pmap_steal_memory 938function is enabled by defining the C pre-processor macro 939.Dv PMAP_STEAL_MEMORY 940in 941.Aq Pa machine/pmap.h . 942.It vaddr_t Fn "pmap_growkernel" "vaddr_t maxkvaddr" 943Management of the kernel virtual address space is complicated by the 944fact that it is not always safe to wait for resources with which to 945map a kernel virtual address. 946However, it is not always desirable to pre-allocate all resources 947necessary to map the entire kernel virtual address space. 948.Pp 949The 950.Fn pmap_growkernel 951interface is designed to help alleviate this problem. 952The virtual memory startup code may choose to allocate an initial set 953of mapping resources (e.g., page tables) and set an internal variable 954indicating how much kernel virtual address space can be mapped using 955those initial resources. 956Then, when the virtual memory system wishes to map something 957at an address beyond that initial limit, it calls 958.Fn pmap_growkernel 959to pre-allocate more sources with which to create the mapping. 960Note that once additional kernel virtual address space mapping resources 961have been allocated, they should not be freed; it is likely they will 962be needed again. 963.Pp 964The 965.Fn pmap_growkernel 966function returns the new maximum kernel virtual address that can be mapped 967with the resources it has available. 968If new resources cannot be allocated, 969.Fn pmap_growkernel 970must panic. 971.Pp 972The 973.Fn pmap_growkernel 974function is enabled by defining the C pre-processor macro 975.Dv PMAP_GROWKERNEL 976in 977.Aq Pa machine/pmap.h . 978.It void Fn "pmap_fork" "pmap_t src_map" "pmap_t dst_map" 979Some 980.Nm 981implementations may need to keep track of other information not 982directly related to the virtual address space. 983For example, on the i386 port, the Local Descriptor Table state of a 984process is associated with the pmap (this is due to the fact that 985applications manipulate the Local Descriptor Table directly expect it 986to be logically associated with the virtual memory state of the process). 987.Pp 988The 989.Fn pmap_fork 990function is provided as a way to associate information from 991.Fa src_map 992with 993.Fa dst_map 994when a 995.Dv vmspace 996is forked. 997.Fn pmap_fork 998is called from 999.Fn uvmspace_fork . 1000.Pp 1001The 1002.Fn pmap_fork 1003function is enabled by defining the C pre-processor macro 1004.Dv PMAP_FORK 1005in 1006.Aq Pa machine/pmap.h . 1007.It vaddr_t Fn "PMAP_MAP_POOLPAGE" "paddr_t pa" 1008This function is used by the 1009.Xr pool 9 1010memory pool manager. 1011Pools allocate backing pages one at a time. 1012This is provided as a means to use hardware features such as a 1013direct-mapped memory segment to map the pages used by the 1014.Xr pool 9 1015allocator. 1016This can lead to better performance by e.g. reducing TLB contention. 1017.Pp 1018.Fn PMAP_MAP_POOLPAGE 1019returns the kernel-accessible address of the page being mapped. 1020It must always succeed. 1021.Pp 1022The use of 1023.Fn PMAP_MAP_POOLPAGE 1024is enabled by defining it as a C pre-processor macro in 1025.Aq Pa machine/pmap.h . 1026If 1027.Fn PMAP_MAP_POOLPAGE 1028is defined, 1029.Fn PMAP_UNMAP_POOLPAGE 1030must also be defined. 1031.Pp 1032The following is an example of how to define 1033.Fn PMAP_MAP_POOLPAGE : 1034.Bd -literal -offset indent 1035#define PMAP_MAP_POOLPAGE(pa) MIPS_PHYS_TO_KSEG0((pa)) 1036.Ed 1037.Pp 1038This takes the physical address of a page and returns the KSEG0 1039address of that page on a MIPS processor. 1040.It paddr_t Fn "PMAP_UNMAP_POOLPAGE" "vaddr_t va" 1041This function is the inverse of 1042.Fn PMAP_MAP_POOLPAGE . 1043.Pp 1044.Fn PMAP_UNMAP_POOLPAGE 1045returns the physical address of the page corresponding to the 1046provided kernel-accessible address. 1047.Pp 1048The use of 1049.Fn PMAP_UNMAP_POOLPAGE 1050is enabled by defining it as a C pre-processor macro in 1051.Aq Pa machine/pmap.h . 1052If 1053.Fn PMAP_UNMAP_POOLPAGE 1054is defined, 1055.Fn PMAP_MAP_POOLPAGE 1056must also be defined. 1057.Pp 1058The following is an example of how to define 1059.Fn PMAP_UNMAP_POOLPAGE : 1060.Bd -literal -offset indent 1061#define PMAP_UNMAP_POOLPAGE(pa) MIPS_KSEG0_TO_PHYS((va)) 1062.Ed 1063.Pp 1064This takes the KSEG0 address of a previously-mapped pool page 1065and returns the physical address of that page on a MIPS processor. 1066.It void Fn "PMAP_PREFER" "vaddr_t hint" "vaddr_t *vap" "vsize_t sz" "int td" 1067This function is used by 1068.Xr uvm_map 9 1069to adjust a virtual address being allocated in order to avoid 1070cache alias problems. 1071If necessary, the virtual address pointed by 1072.Fa vap 1073will be advanced. 1074.Fa hint 1075is an object offset which will be mapped into the resulting virtual address, and 1076.Fa sz 1077is size of the object. 1078.Fa td 1079indicates if the machine dependent pmap uses the topdown VM. 1080.Pp 1081The use of 1082.Fn PMAP_PREFER 1083is enabled by defining it as a C pre-processor macro in 1084.Aq Pa machine/pmap.h . 1085.Pp 1086.It void Fn "pmap_procwr" "struct proc *p" "vaddr_t va" "vsize_t size" 1087Synchronize CPU instruction caches of the specified range. 1088The address space is designated by 1089.Fa p . 1090This function is typically used to flush instruction caches 1091after code modification. 1092.Pp 1093The use of 1094.Fn pmap_procwr 1095is enabled by defining a C pre-processor macro 1096.Dv PMAP_NEED_PROCWR 1097in 1098.Aq Pa machine/pmap.h . 1099.El 1100.Sh SEE ALSO 1101.Xr uvm 9 1102.Sh HISTORY 1103The 1104.Nm 1105module was originally part of the design of the virtual memory system 1106in the Mach Operating System. 1107The goal was to provide a clean separation between the machine-independent 1108and the machine-dependent portions of the virtual memory system, in 1109stark contrast to the original 1110.Bx 3 1111virtual memory system, which was specific to the VAX. 1112.Pp 1113Between 1114.Bx 4.3 1115and 1116.Bx 4.4 , 1117the Mach virtual memory system, including the 1118.Nm 1119API, was ported to 1120.Bx 1121and included in the 1122.Bx 4.4 1123release. 1124.Pp 1125.Nx 1126inherited the 1127.Bx 1128version of the Mach virtual memory system. 1129.Nx 1.4 1130was the first 1131.Nx 1132release with the new 1133.Xr uvm 9 1134virtual memory system, which included several changes to the 1135.Nm 1136API. 1137Since the introduction of 1138.Xr uvm 9 , 1139the 1140.Nm 1141API has evolved further. 1142.Sh AUTHORS 1143The original Mach VAX 1144.Nm 1145module was written by 1146.An Avadis Tevanian, Jr. 1147and 1148.An Michael Wayne Young . 1149.Pp 1150.An Mike Hibler 1151did the integration of the Mach virtual memory system into 1152.Bx 4.4 1153and implemented a 1154.Nm 1155module for the Motorola 68020+68851/68030/68040. 1156.Pp 1157The 1158.Nm 1159API as it exists in 1160.Nx 1161is derived from 1162.Bx 4.4 , 1163and has been modified by 1164.An Chuck Cranor , 1165.An Charles M. Hannum , 1166.An Chuck Silvers , 1167.An Wolfgang Solfrank , 1168.An Bill Sommerfeld , 1169and 1170.An Jason R. Thorpe . 1171.Pp 1172The author of this document is 1173.An Jason R. Thorpe 1174.Aq thorpej@NetBSD.org . 1175.Sh BUGS 1176The use and definition of 1177.Fn pmap_activate 1178and 1179.Fn pmap_deactivate 1180needs to be reexamined. 1181.Pp 1182The use of 1183.Fn pmap_copy 1184needs to be reexamined. 1185Empirical evidence suggests that performance of the system suffers when 1186.Fn pmap_copy 1187actually performs its defined function. 1188This is largely due to the fact that the copy of the virtual-to-physical 1189mappings is wasted if the process calls 1190.Xr execve 2 1191after 1192.Xr fork 2 . 1193For this reason, it is recommended that 1194.Nm 1195implementations leave the body of the 1196.Fn pmap_copy 1197function empty for now. 1198