Contents
Managing virtual memory (vmm_api.h)
The API is defined in the header file sysroot-*-kos/include/coresrv/vmm/vmm_api.h
from the KasperskyOS SDK.
The API is designed to allocate and free memory, create shared memory, and prepare ELF image segments to be loaded into process memory.
Allocating and freeing memory
Information about API functions is provided in the table below.
Using the API
Virtual memory pages may be free, reserved, or committed. Free pages that are used to allocate a virtual memory region become reserved pages. Reserved pages may or may not be mapped to physical memory. Reserved pages that are mapped to physical memory are committed pages.
Pages of a virtual memory region that are allocated by the KnVmAllocate()
function call can be committed in three different ways:
- Fully committed when the region is allocated.
- Fully or partially committed after allocation of the region (by calling the
KnVmCommit()
function). - Committed whenever virtual addresses are queried (so-called "lazy" mode).
When the first option is used, the entire required volume of physical memory is allocated immediately after the virtual memory region is reserved. When the second or third option is used, the virtual memory region is reserved without allocating physical memory. This lets you conserve physical memory if a reserved virtual memory region will not actually be required or will only be partially used. In addition, a virtual memory region can be allocated faster if its allocation does not include commitment.
When in "lazy" mode, physical memory is allocated only when the virtual memory region is actually queried. In this case, the page containing the queried address and several pages before and after this address are committed.
If you call the KnVmAllocate()
function with the VMM_FLAG_COMMIT
and VMM_FLAG_LOCKED
flags, the virtual memory region will be reserved and fully committed. If you call the KnVmAllocate()
function with the VMM_FLAG_COMMIT
flag but without the VMM_FLAG_LOCKED
flag, the virtual memory region will be reserved and committed only in "lazy" mode. If you call the KnVmAllocate()
function with the VMM_FLAG_LOCKED
flag but without the VMM_FLAG_COMMIT
flag, the virtual memory region will be reserved without commitment and a subsequent call of the KnVmCommit()
function will fully commit this region. If you call the KnVmAllocate()
function without the VMM_FLAG_COMMIT
and VMM_FLAG_LOCKED
flags, the virtual memory region will be reserved without commitment and a subsequent call of the KnVmCommit()
function will commit this region in "lazy" mode.
A virtual memory region is allocated when the MDL buffer, DMA buffer or MMIO memory region is mapped to process memory. This region is allocated by the mapping function.
A protected page may reside at the beginning and/or end of the virtual memory region. This page is never committed. Any query of this page will result in an exception signaling that the region boundaries have been exceeded.
To change the access rights to the virtual memory region, call the KnVmProtect()
function. You can fully close and then re-open access to a region while retaining is contents.
To free physical memory while retaining the reservation of virtual addresses, call the KnVmDecommit()
or KnVmReset()
function. In this case, the contents of the virtual memory region will be lost. After freeing physical memory by calling the KnVmDecommit()
function, you must call the KnVmCommit()
function to subsequently use the virtual memory region. After freeing physical memory by calling the KnVmReset()
function, the virtual memory region can be used without any additional actions required. This virtual memory region will correspond to memory allocated by calling the KnVmAllocate()
function with the VMM_FLAG_COMMIT
flag but without the VMM_FLAG_LOCKED
flag.
The KnVmProtect()
, KnVmDecommit()
, and KnVmReset()
functions cannot be used if the MDL buffer, DMA buffer or MMIO memory region is mapped to the virtual memory region.
To free the virtual memory region, call the KnVmUnmap()
function. When this function is called, the reserved pages will become free regardless of whether or not they were committed, and the physical memory mapped to committed pages is also freed.
The KnVmUnmap()
function frees the virtual addresses of a region mapped to the MDL buffer, but does not delete the MDL buffer. In addition, this function cannot be used if the DMA buffer or MMIO memory region is mapped to the virtual memory region.
The KnVmCommit()
, KnVmProtect()
, KnVmDecommit()
, KnVmReset()
, and KnVmUnmap()
functions can be applied for the entire allocated virtual memory region or for a portion of it.
The functions presented in this section provide the basis for implementing memory allocation/deallocation functions of the libkos library, and functions of POSIX interfaces such as malloc()
, calloc()
, realloc()
, free()
, mmap()
, and munmap()
.
Information about API functions
vmm_api.h functions
Function |
Information about the function |
---|---|
|
Purpose Allocates (reserves and optionally commits) a virtual memory region. Parameters
Returned values If successful, the function returns the base address of the allocated virtual memory region, otherwise it returns Additional information In the
Permissible combinations of flags defining the access rights to the virtual memory region:
|
|
Purpose Commits a virtual memory region. Parameters
Returned values If successful, the function returns |
|
Purpose Decommits a virtual memory region. Parameters
Returned values If successful, the function returns |
|
Purpose Modifies the access rights to the virtual memory region. Parameters
Returned values If successful, the function returns Additional information In the
|
|
Purpose Frees up the virtual memory region. Parameters
Returned values If successful, the function returns |
|
Purpose Gets information about a virtual memory page. Parameters
Returned values If successful, the function returns |
|
Purpose Decommits a virtual memory region. Parameters
Returned values If successful, the function returns |
Creating shared memory
Information about API functions is provided in the table below.
Using the API
An MDL buffer is used to create shared memory. An MDL buffer consists of one or more physical memory regions that can be mapped to the memory of multiple processes at the same time. A kernel object known as a memory descriptor list is used to map the MDL buffer to process memory. A memory descriptor list (MDL) is a data structure containing the addresses and sizes of physical memory regions comprising the MDL buffer. The MDL buffer handle identifies the memory descriptor list.
To create shared memory, a process needs to create an MDL buffer, map it to its own memory, and pass the MDL buffer handle via IPC to other processes that also need to map this MDL buffer to their own memory.
To create an MDL buffer, call the KnPmmMdlCreate()
, KnPmmMdlCreateFromBuf()
or KnPmmMdlCreateFromVm()
function. The KnPmmMdlCreateFromBuf()
function creates an MDL buffer and copies data to it. The KnPmmMdlCreateFromVm()
function creates an MDL buffer and maps it to the memory of the calling process.
To reserve a virtual memory region and map the MDL buffer to it, call the KnPmmMdlMap()
function. An MDL buffer can be mapped to multiple virtual memory regions of the same process.
An MDL buffer can be used to transfer large volumes of data between processes without creating shared memory. In this case, you must make sure that the MDL buffer is not mapped to the memory of multiple processes at the same time. Interacting processes must take turns mapping the MDL buffer to their own memory, reading and/or writing data and then freeing the virtual memory region that is mapped to this MDL buffer.
The Kaspersky Security Module cannot control data that is transferred between processes via the MDL buffer.
Deleting an MDL buffer
To delete an MDL buffer, complete the following steps:
- Free the virtual memory regions mapped to the MDL buffer in all processes that are using this MDL buffer.
To complete this step, use the
KnVmUnmap()
function. - Close or revoke each MDL buffer handle in all processes that own these handles.
To complete this step, use the
KnHandleClose()
and/orKnHandleRevoke()
functions that are declared in the header filesysroot-*-kos/include/coresrv/handle/handle_api.h
from the KasperskyOS SDK.
Information about API functions
vmm_api.h functions
Function |
Information about the function |
---|---|
|
Purpose Creates an MDL buffer. Parameters
Returned values If successful, the function returns Additional information In the
|
|
Purpose Creates an MDL buffer from physical memory that is mapped to the defined virtual memory region and maps the created MDL buffer to this region. Parameters
Returned values If successful, the function returns Additional information This function can be used if the defined virtual memory region is allocated with commitment. In the
|
|
Purpose Creates an MDL buffer and copies data from the defined buffer to the MDL buffer. Parameters
Returned values If successful, the function returns Additional information In the
|
|
Purpose Gets the size of the MDL buffer. Parameters
Returned values If successful, the function returns |
|
Purpose Reserves a virtual memory region and maps the MDL buffer to it. Parameters
Returned values If successful, the function returns Additional information In the
Permissible combinations of flags defining the access rights to the virtual memory region:
|
|
Purpose Creates an MDL buffer based on an existing one. The MDL buffer is created from the same regions of physical memory as the original buffer. Parameters
Returned values If successful, the function returns |
Preparing ELF image segments to be loaded into process memory
Information about API functions is provided in the table below.
Using the API
MDL buffers are used not only to create shared memory, but also to load ELF image segments into the memory of a new process. (ELF image segments are loaded by the Einit
initializing program, for example.)
The KnVmSegInitFromVm()
and KnVmSegInitFromBuf()
functions create an MDL buffer and put the ELF image segment into it so that this segment can then be loaded into the memory of a new process.
Deleting MDL buffers containing ELF image segments
To delete MDL buffers containing ELF image segments, you must terminate the new process whose memory is mapped to these MDL buffers. You also need to complete the following steps before or after termination of this process:
- Free the virtual memory regions that are mapped to the MDL buffers in the process that created these MDL buffers.
This step is required only for MDL buffers that were created using the
KnVmSegInitFromVm()
function.To complete this step, use the
KnVmUnmap()
function. - Close the handles of MDL buffers in the process that created these MDL buffers.
To complete this step, use the
KnHandleClose()
function, which is declared in the header filesysroot-*-kos/include/coresrv/handle/handle_api.h
from the KasperskyOS SDK.
Information about API functions
vmm_api.h functions
Function |
Information about the function |
---|---|
|
Purpose Creates an MDL buffer from physical memory that is mapped to the defined virtual memory region containing the ELF image segment. Parameters
Returned values If successful, the function returns Additional information This function can be used if the defined virtual memory region is allocated with commitment. In the
|
|
Purpose Creates an MDL buffer and copies the ELF image segment from the defined buffer to the MDL buffer. Parameters
Returned values If successful, the function returns Additional information In the
|