blob: 8e8ee1f7fddf1a3ac72605bdd9876770299b7fb4 [file] [log] [blame] [view]
# Virtual Memory Address Region
## NAME
vm_address_region - A contiguous region of a virtual memory address space
## SYNOPSIS
Virtual Memory Address Regions (VMARs) represent contiguous parts of a virtual
address space.
## DESCRIPTION
VMARs are used by the kernel and userspace to represent the allocation of an
address space.
Every process starts with a single VMAR (the root VMAR) that spans the entire
address space (see [`zx_process_create()`]). Each VMAR
can be logically divided up into any number of non-overlapping parts, each
representing a child VMARs, a virtual memory mapping, or a gap. Child VMARs
are created using [`zx_vmar_allocate()`]. VM mappings
are created using [`zx_vmar_map()`].
VMARs have a hierarchical permission model for allowable mapping permissions.
For example, the root VMAR allows read, write, and executable mapping. One
could create a child VMAR that only allows read and write mappings, in which
it would be illegal to create a child that allows executable mappings.
When a VMAR is created using [`zx_vmar_allocate()`], its parent VMAR retains a reference
to it. Because of this, if all handles to the child VMAR are closed, the child
and its descendants will remain active in the address space. In order to
disconnect the child from the address space, [`zx_vmar_destroy()`]
must be called on a handle to the child.
By default, all allocations of address space are randomized. At VMAR
creation time, the caller can choose which randomization algorithm is used.
The default allocator attempts to spread allocations widely across the full
width of the VMAR. The alternate allocator, selected with
**ZX_VM_COMPACT**, attempts to keep allocations close together within the
VMAR, but at a random location within the range. It is recommended to use
the default allocator.
VMARs optionally support a fixed-offset mapping mode (called specific mapping).
This mode can be used to create guard pages or ensure the relative locations of
mappings. Each VMAR may have the **ZX_VM_CAN_MAP_SPECIFIC** permission,
regardless of whether or not its parent VMAR had that permission.
## EXAMPLE
```c
#include <zircon/syscalls.h>
/* Map this VMO into the given VMAR, with |before| bytes of unmapped guard space
before it and |after| bytes after it. */
zx_status_t map_with_guard(zx_handle_t vmar, size_t before, size_t after,
zx_handle_t vmo, uint64_t vmo_offset,
size_t mapping_len, uintptr_t* mapped_addr,
zx_handle_t* wrapping_vmar) {
/* wrap around check elided */
const size_t child_vmar_size = before + after + mapping_len;
const zx_vm_option_t child_vmar_options = ZX_VM_CAN_MAP_READ |
ZX_VM_CAN_MAP_WRITE |
ZX_VM_CAN_MAP_SPECIFIC;
const zx_vm_option_t mapping_options = ZX_VM_SPECIFIC |
ZX_VM_PERM_READ |
ZX_VM_PERM_WRITE;
uintptr_t child_vmar_addr;
zx_handle_t child_vmar;
zx_status_t status = zx_vmar_allocate(vmar, child_vmar_options, 0,
child_vmar_size,
&child_vmar,
&child_vmar_addr);
if (status != ZX_OK) {
return status;
}
status = zx_vmar_map(child_vmar, mapping_options, before, vmo, vmo_offset,
mapping_len, mapped_addr);
if (status != ZX_OK) {
zx_vmar_destroy(child_vmar);
zx_handle_close(child_vmar);
return status;
}
*wrapping_vmar = child_vmar;
return ZX_OK;
}
```
## SEE ALSO
- [vm_object](vm_object.md) - Virtual Memory Objects
## SYSCALLS
- [`zx_vmar_allocate()`] - create a new child VMAR
- [`zx_vmar_map()`] - map a VMO into a process
- [`zx_vmar_unmap()`] - unmap a memory region from a process
- [`zx_vmar_protect()`] - adjust memory access permissions
- [`zx_vmar_destroy()`] - destroy a VMAR and all of its children
[`zx_process_create()`]: /reference/syscalls/process_create.md
[`zx_vmar_allocate()`]: /reference/syscalls/vmar_allocate.md
[`zx_vmar_destroy()`]: /reference/syscalls/vmar_destroy.md
[`zx_vmar_map()`]: /reference/syscalls/vmar_map.md
[`zx_vmar_protect()`]: /reference/syscalls/vmar_protect.md
[`zx_vmar_unmap()`]: /reference/syscalls/vmar_unmap.md