OpenBSD manual page server

Manual Page Search Parameters

PMAP_INIT(9) Kernel Developer's Manual PMAP_INIT(9)

pmap_init, pmap_enter, pmap_kenter_pa, pmap_remove, pmap_kremove pmap_unwire, pmap_protect, pmap_page_protect, pmap_is_modified, pmap_clear_modify, pmap_is_referenced, pmap_clear_reference, pmap_copy_page, pmap_zero_page, pmap_create, pmap_reference, pmap_destroy, pmap_steal_memory, pmap_growkernel, pmap_update, pmap_collect, pmap_virtual_space, pmap_copy, — machine dependent interface to the MMU

#include <machine/pmap.h>

The architecture-dependent pmap module describes how the physical mapping is done between the user-processes and kernel virtual addresses and the physical addresses of the main memory, providing machine-dependent translation and access tables that are used directly or indirectly by the memory-management hardware. The pmap layer can be viewed as a big array of mapping entries that are indexed by virtual address to produce a physical address and flags. These flags describe the page's protection, whether the page has been referenced or modified and other characteristics.

The pmap interface is consistent across all platforms and hides the way page mappings are stored.

void
(void);

The () function is called from the machine-independent uvm(9) initialization code, when the MMU is enabled.

Modified/referenced information is only tracked for pages managed by uvm(9) (pages for which a vm_page structure exists). Only managed mappings of those pages have modified/referenced tracking. The use of unmanaged mappings should be limited to code which may execute in interrupt context (such as malloc(9)) or to enter mappings for physical addresses which are not managed by uvm(9). This allows pmap modules to avoid blocking interrupts when manipulating data structures or holding locks. Unmanaged mappings may only be entered into the kernel's virtual address space. The modified/referenced bits must be tracked on a per-page basis, as they are not attributes of a mapping, but attributes of a page. Therefore, even after all mappings for a given page have been removed, the modified/referenced bits for that page must be preserved. The only time the modified/referenced bits may be cleared is when uvm(9) explicitly calls the () and () functions. These functions must also change any internal state necessary to detect the page being modified or referenced again after the modified/referenced state is cleared.

Mappings entered by () are managed, mappings entered by pmap_kenter_pa() are not.

int
pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags);

void
pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot);

void
pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva);

void
pmap_kremove(vaddr_t va, vsize_t size);

The () function creates a managed mapping for physical page pa at the specified virtual address va in the target physical map pmap with protection specified by prot:

PROT_READ
The mapping must allow reading.
PROT_WRITE
The mapping must allow writing.
PROT_EXEC
The page mapped contains instructions that will be executed by the processor.

The flags argument contains protection bits (the same bits used in the prot argument) indicating the type of access that caused the mapping to be created. This information may be used to seed modified/referenced information for the page being mapped, possibly avoiding redundant faults on platforms that track modified/referenced information in software. Other information provided by flags:

PMAP_WIRED
The mapping being created is a wired mapping.
PMAP_CANFAIL
The call to () is allowed to fail. If this flag is not set, and the pmap_enter() call is unable to create the mapping, perhaps due to insufficient resources, the pmap module must panic.

The access type provided in the flags argument will never exceed the protection specified by prot.

The () function is called by the fault routine to establish a mapping for the page being faulted in. If pmap_enter() is called to enter a mapping at a virtual address for which a mapping already exists, the previous mapping must be invalidated. pmap_enter() is sometimes called to change the protection for a pre-existing mapping, or to change the “wired” attribute for a pre-existing mapping.

The () function creates an unmanaged mapping of physical address pa at the specified virtual address va with the protection specified by prot.

The () function removes the range of virtual addresses sva to eva from pmap, assuming proper alignment. pmap_remove() is called during an unmap operation to remove low-level machine dependent mappings.

The () function removes an unmanaged mapping at virtual address va of size size.

A call to () must be made after pmap_kenter_pa() or pmap_kremove() to notify the pmap layer that the mappings need to be made correct.

void
pmap_unwire(pmap_t pmap, vaddr_t va);

void
pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot);

void
pmap_page_protect(struct vm_page *pg, vm_prot_t prot);

The () function clears the wired attribute for a map/virtual-address pair. The mapping must already exist in pmap.

The () function sets the physical protection on range sva to eva, in pmap.

The () function is called during a copy-on-write operation to write protect copy-on-write memory, and when paging out a page to remove all mappings of a page. The () function sets the permission for all mapping to page pg. The pmap_page_protect() function is called before a pageout operation to ensure that all pmap references to a page are removed.

boolean_t
pmap_is_modified(struct vm_page *pg);

boolean_t
pmap_clear_modify(struct vm_page *pg);

boolean_t
pmap_is_referenced(struct vm_page *pg);

boolean_t
pmap_clear_reference(struct vm_page *pg);

The () and () functions read/set the modify bits on the specified physical page pg. The pmap_is_referenced() and pmap_clear_reference() functions read/set the reference bits on the specified physical page pg.

The () and pmap_is_modified() functions are called by the pagedaemon when looking for pages to free. The () and pmap_clear_modify() functions are called by the pagedaemon to help identification of pages that are no longer in demand.

void
pmap_copy_page(struct vm_page *src, struct vm_page *dst);

void
pmap_zero_page(struct vm_page *page);

The () function copies the content of the physical page src to physical page dst.

The () function fills page with zeroes.

pmap_t
pmap_create(void);

void
pmap_reference(pmap_t pmap);

void
pmap_destroy(pmap_t pmap);

The () function creates an instance of the pmap structure.

The () function increments the reference count on pmap.

The () function decrements the reference count on physical map pmap and retires it from service if the count drops to zero, assuming it contains no valid mappings.

vaddr_t
pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp);

vaddr_t
pmap_growkernel(vaddr_t maxkvaddr);

void
pmap_update(pmap_t pmap);

void
pmap_collect(pmap_t pmap);

void
pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp);

void
pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_addr, vsize_t len, vaddr_t src_addr);

Wired memory allocation before the virtual memory system is bootstrapped is accomplished by the () function. After that point, the kernel memory allocation routines should be used.

The () function can preallocate kernel page tables to a specified virtual address.

The () function notifies the pmap module to force processing of all delayed actions for all pmaps.

The () function informs the pmap module that the given pmap is not expected to be used for some time, giving the pmap module a chance to prioritize. The initial bounds of the kernel virtual address space are returned by ().

The () function copies the range specified by src_addr and src_len from src_pmap to the range described by dst_addr and dst_len in dst_map. pmap_copy() is called during a fork(2) operation to give the child process an initial set of low-level mappings.

fork(2), uvm(9)

The 4.4BSD pmap module is based on Mach 3.0. The introduction of uvm(9) left the pmap interface unchanged for the most part.

Ifdefs must be documented.

pmap_update() should be mandatory.

March 21, 2016 OpenBSD-6.0