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