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