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