The virtual memory manager supports functions that allow a wide range of kernel extension data operations.
The following aspects of the virtual memory manager interface are discussed:
A virtual memory object is an abstraction for the contiguous data that can be mapped into a region of an address space. As a data object, it is independent of any address space. The data it represents can be in memory or on an external storage device. The data represented by the virtual memory object can be shared by mapping the virtual memory object into each address space sharing the access, with the access capability of each mapping represented in that address space map.
File systems use virtual memory objects so that the files can be referenced using a mapped file access method. The mapped file access method represents the data through a virtual memory object, and allows the virtual memory manager to handle page faults on the mapped file. When a page fault occurs, the virtual memory manager calls the services supplied by the service provider (such as a virtual file system) to get and put pages. A data provider (such as a file system) maintains any data structures necessary to map between the virtual memory object offset and external storage addressing.
The data provider creates a virtual memory object when it has a request for access to the data. It deletes the virtual memory object when it has no more clients referencing the data in the virtual memory object.
The vms_create service is called to create virtual memory objects. The vms_delete service is called to delete virtual memory objects.
Data in a virtual memory object is made addressable in user or kernel processes through the shmat subroutine. A kernel extension uses the vm_att kernel service to select and allocate a region in the current (per-process kernel) address space.
The per-process kernel address space initially sees only global kernel memory and the per-process kernel data. The vm_att service allows kernel extensions to allocate additional regions. However, this augmented per-process kernel address space does not persist across system calls. The additional regions must be re-allocated with each entry into the kernel protection domain.
The vm_att service takes as an argument a virtual memory handle representing the virtual memory object and the access capability to be used. The vm_handle service constructs the virtual memory handles.
When the kernel extension has finished processing the data mapped into the current address space, it should call the vm_det service to deallocate the region and remove access.
A data provider (such as a file system) can call the vm_makep service to cause a memory page to be instantiated. This permits a page of data to be moved into a virtual memory object page without causing the virtual memory manager to page in the previous data contents from an external source. This is an operation on the virtual memory object, not an address space range.
The vm_move and vm_uiomove kernel services move data between a virtual memory object and a buffer specified in a uio structure. This allows data providers (such as a file system) to move data to or from a specified buffer to a designated offset in a virtual memory object. This service is similar to uiomove service, but the trusted buffer is replaced by the virtual memory object, which need not be currently addressable.
A kernel extension can initiate the writing of a data area to external storage with the vm_write kernel service, if it has addressability to the data area. The vm_writep kernel service can be used if the virtual memory object is not currently addressable.
If the kernel extension needs to ensure that the data is moved successfully, it can wait on the I/O completion by calling the vms_iowait service, giving the virtual memory object as an argument.
The pages specified by a data range can be released from the underlying virtual memory object by calling the vm_release service. The virtual memory manager deallocates any associated paging space slots. A subsequent reference to data in the range results in a page fault.
A virtual memory data provider can release a specified range of pages in a virtual memory object by calling the vm_releasep service. The virtual memory object need not be addressable for this call.
The vm_protectp service can change the storage protect keys in a page range in one client storage virtual memory object. This only acts on the resident pages. The pages are referred to through the virtual memory object. They do not need to be addressable in the current address space. A client file system data provider uses this protection to detect stores of in-memory data, so that mapped files can be extended by storing into them beyond their current end of file.
If the data moved is to become executable, any data remaining in processor cache must be guaranteed to be moved from cache to memory. This is because the retrieval of the instruction does not need to use the data cache. The vm_cflush service performs this operation.
The kernel extension data providers must provide appropriate routines to be called by the virtual memory manager. These routines move a page-sized block of data into or out of a specified page. These services are also referred to as pager backends.
For a local device, the device strategy routine is required. A call to the vm_mount service is used to identify the device (through a dev_t value) to the virtual memory manager.
For a remote data provider, the routine required is a strategy routine, which is specified in the vm_mount service. These strategy routines must run as interrupt-level routines. They must not page fault, and they cannot sleep waiting for locks.
When access to a remote data provider or a local device is removed, the vm_umount service must be called to remove the device entry from the virtual memory manager's paging device table.
The virtual memory manager exports these routines exported to kernel extensions:
Services That Manipulate Virtual Memory Objects | |
---|---|
vm_att | Selects and allocates a region in the current address space for the specified virtual memory object. |
vms_create | Creates virtual memory object of the specified type and size limits. |
vms_delete | Deletes a virtual memory object. |
vm_det | Unmaps and deallocates the region at a specified address in the current address space. |
vm_handle | Constructs a virtual memory handle for mapping a virtual memory object with a specified access level. |
vms_iowait | Waits for the completion of all page-out operations in the virtual memory object. |
vm_makep | Makes a page in client storage. |
vm_move | Moves data between the virtual memory object and buffer specified in the uio structure. |
vm_protectp | Sets the page protection key for a page range. |
vm_releasep | Releases page frames and paging space slots for pages in the specified range. |
vm_uiomove | Moves data between the virtual memory object and buffer specified in the uio structure. |
vm_vmid | Converts a virtual memory handle to a virtual memory object (id). |
vm_writep | Initiates page-out for a page range in a virtual memory object. |
The following services support address space operations:
as_att | Selects, allocates, and maps a region in the specified address space for the specified virtual memory object. |
as_det | Unmaps and deallocates a region in the specified address space that was mapped with the as_att kernel service. |
as_geth | Obtains a handle to the virtual memory object for the specified address given in the specified address space. The virtual memory object is protected. |
as_getsrval | Obtains a handle to the virtual memory object for the specified address given in the specified address space. |
as_puth | Indicates that no more references will be made to a virtual memory object that was obtained using the as_geth kernel service. |
as_seth | Maps a specified region in the specified address space for the specified virtual memory object. |
getadsp | Obtains a pointer to the current process's address space structure for use with the as_att and as_det kernel services. |
vm_cflush | Flushes cache lines for a specified address range. |
vm_release | Releases page frames and paging space slots for the specified address range. |
vm_write | Initiates page-out for an address range. |
The following Memory-Pinning kernel services also support address space operations. They are the pin, pinu, unpin, and unpinu services.
Services That Support Cross-Memory Operations |
---|
Cross Memory Services are listed in "Memory Kernel Services". |
Services that Support the Installation of Pager Backends | |
---|---|
vm_mount | Allocates an entry in the paging device table. |
vm_umount | Removes a file system from the paging device table. |
as_att64 | Allocates and maps a specified region in the current user address space. |
as_det64 | Unmaps and deallocates a region in the current user address space that was mapped with the as_att64 kernel service. |
as_geth64 | Obtains a handle to the virtual memory object for the specified address. |
as_puth64 | Indicates that no more references will be made to a virtual memory object using the as_geth64 kernel service. |
as_seth64 | Maps a specified region for the specified virtual memory object. |
as_getsrval64 | Obtains a handle to the virtual memory object for the specified address. |
IS64U | Determines if the current user address space is 64-bit or not. |
The following services are supported only on the 32-bit kernel:
as_remap64 | Maps a 64-bit address to a 32-bit address that can be used by the 32-bit kernel. |
as_unremap64 | Returns the original 64-bit original address associated with a 32-bit mapped address. |
rmmap_create64 | Defines an effective address to real address translation region for either 64-bit or 32-bit effective addresses. |
rmmap_remove64 | Destroys an effective address to real address translation region. |
xmattach64 | Attaches to a user buffer for cross-memory operations. |
copyin64 | Copies data between user and kernel memory. |
copyout64 | Copies data between user and kernel memory. |
copyinstr64 | Copies data between user and kernel memory. |
fubyte64 | Retrieves a byte of data from user memory. |
fuword64 | Retrieves a word of data from user memory. |
subyte64 | Stores a byte of data in user memory. |
suword64 | Stores a word of data in user memory. |