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