The Simple Virtual Memory (SVM) component provides very simple virtual memory management routines that are somewhat more application friendly than the extremely basic support provided by the kernel library (see Section 15.9.11). Applications are able to allocate large contiguous blocks of virtual memory that are backed by physical memory. Applications may also control the page level protection of memory. In addition, there is optional pageout support that allows the application to allocate more virtual memory than physical memory on machines where a disk swap partition is available. The SVM component is thread safe, although only a single virtual memory context is provided; all threads share the same set of page tables.
The SVM manager makes use of the list-based memory manager (LMM) (see Section 25), the address map manager (AMM) (see Section 26), and the page directory support in the kernel library. The LMM is used to to control physical memory, while the AMM is used to control the virtual memory mappings. The kernel paging support handles the details of manipulating the low level page tables. As a result, the SVM manager is very simple in its construction.
Although on the surface it might appear that the SVM provides generalized VM support, nothing could be further from the truth. What is provided is a means to allocate memory in the range above existing physical memory, and map those ranges to physical pages. With paging enabled, the application is able to use more virtual memory than physical memory. It should be noted that the kernel remains where it was initially loaded, and that unused pages of physical memory are left accessible by the application.
This function initializes the SVM system, turning on base paging support (see Section 15.9.1), and optionally configuring pageout support. The pager_absio argument is optional, and if specified should be a device suitable for use as the swap area for the pager. pager_absio may also be a oskit_blkio_t; the pager will query the object to determine which type it is. Only a single paging area is supported. The initialization code will create an initial set of page tables that maps all of physical memory as readable and writable, except for kernel text which is mapped read-only. A stack redzone is also created, although stack overflows are fatal since there is not enough support to allow recovery. The address range above the end of physical memory is mapped as invalid so that accesses result in a page fault trap (instead of silently returning bogus data).
In the case of a multi-threaded kernel, pager_absio must be a properly wrapped object (see Section 29.5). The current multi-threaded locking strategy is extremely simple; a single lock protects the entire SVM module.
#include <oskit/svm/svm.h>
int svm_alloc(oskit_addr_t *addr, oskit_size_t length, int prot, int flags);
Allocate a region of virtual memory, returning the base address of the new region in addr. The region is length bytes in size, and is initialized to the page level protection specified by prot. The size of the allocation must be an integral number of pages. The caller can optionally specify the (page aligned) base address at which to place the region by providing a non-zero value in addr. The actual base address might differ if the system cannot place the region at that address. Alternatively, if the flags value contains SVM_ALLOC_FIXED, and the region cannot be placed at the requested address, the allocation will fail and return an error code.
Returns zero on success. Returns OSKIT_E_INVALIDARG if either the base address or the size of the allocation is not page aligned. Returns OSKIT_E_OUTOFMEMORY if the region cannpt be assigned to the fixed location requested by the caller.
svm_dealloc, svm_protect
Deallocate a range of memory that was previously allocated with svm_alloc. The range starts at addr, and is length bytes in size. The base address must be page aligned, and the length must be an integral number of pages. The range may be a subset of a previously allocated range; only that subset is deallocated.
Returns zero on success. Returns OSKIT_E_INVALIDARG if either the base address or the size of the allocation is not page aligned, or if the range is not within an existing allocation.
svm_alloc, svm_protect
Change the page level protection on a region of memory. The region begins at addr and extends for length bytes. The base address must be page aligned, and the length must be an integral number of pages. The page level protection of each page in the region is set to prot. Unlike svm_dealloc, this routine may called on any region of memory, not just regions that were allocated with svm_alloc.
Returns zero on success. Returns OSKIT_E_INVALIDARG if either the base address or the size of the allocation is not page aligned.
svm_alloc, svm_dealloc