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