blob: f25a055994bcbc8b364f29e6ca1b2b43c9c0713f [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library zx;
alias VmOption = uint32;
// TODO(scottmg): bits for ZX_VM_xyz flags, and const for ZX_VM_ALIGN_xyz.
@transport("Syscall")
closed protocol Vmar {
/// ## Summary
///
/// Allocate a new subregion.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vmar_allocate(zx_handle_t parent_vmar,
/// zx_vm_option_t options,
/// size_t offset,
/// size_t size,
/// zx_handle_t* child_vmar,
/// zx_vaddr_t* child_addr);
/// ```
///
/// ## Description
///
/// Creates a new VMAR within the one specified by *parent_vmar*.
///
/// *options* is a bit vector that contains one more of the following:
///
/// - `ZX_VM_COMPACT` A hint to the kernel that allocations and mappings
/// within the newly created subregion should be kept close together. See the
/// NOTES section below for discussion.
/// - `ZX_VM_SPECIFIC` Use the *offset* to place the mapping, invalid if
/// *parent_vmar* does not have the `ZX_VM_CAN_MAP_SPECIFIC` permission. *offset*
/// is an offset relative to the base address of the parent region. It is an error
/// to specify an address range that overlaps with another VMAR or mapping.
/// - `ZX_VM_OFFSET_IS_UPPER_LIMIT` Interpret the *offset* as an upper limit
/// to constrain the selection of the offset by the kernel, invalid if *parent_vmar*
/// does not have the `ZX_VM_CAN_MAP_SPECIFIC` permission. The resulting mapping
/// will have an offset + *size* that is <= *offset*. This option cannot be
/// specified if `ZX_VM_SPECIFIC` is used.
/// - `ZX_VM_CAN_MAP_SPECIFIC` The new VMAR can have subregions/mappings
/// created with `ZX_VM_SPECIFIC`. It is NOT an error if the parent does
/// not have `ZX_VM_CAN_MAP_SPECIFIC` permissions.
/// - `ZX_VM_CAN_MAP_READ` The new VMAR can contain readable mappings.
/// It is an error if the parent does not have `ZX_VM_CAN_MAP_READ` permissions.
/// - `ZX_VM_CAN_MAP_WRITE` The new VMAR can contain writable mappings.
/// It is an error if the parent does not have `ZX_VM_CAN_MAP_WRITE` permissions.
/// - `ZX_VM_CAN_MAP_EXECUTE` The new VMAR can contain executable mappings.
/// It is an error if the parent does not have `ZX_VM_CAN_MAP_EXECUTE` permissions.
///
/// *offset* must be 0 if *options* does not have `ZX_VM_SPECIFIC` or
/// `ZX_VM_OFFSET_IS_UPPER_LIMIT` set.
///
/// In addition, the following power-of-two alignment flags can added:
///
/// - `ZX_VM_ALIGN_1KB` aligns *child_addr* to a power-of-2 at least 1K bytes.
/// - `ZX_VM_ALIGN_2KB` aligns *child_addr* to a power-of-2 at least 2K bytes.
/// - `ZX_VM_ALIGN_4KB` aligns *child_addr* to a power-of-2 at least 4K bytes.
/// - `ZX_VM_ALIGN_8KB` aligns *child_addr* to a power-of-2 at least 8K bytes.
///
/// and continues up to
///
/// - `ZX_VM_ALIGN_4GB` aligns *child_addr* to a power-of-2 at least 4G bytes.
///
/// Using `ZX_VM_ALIGN` flags with `ZX_VM_SPECIFIC` will fail if the
/// *parent_vmar* base address + *offset* are not aligned to the requested
/// value.
///
/// ## Rights
///
/// If *options* & `ZX_VM_CAN_MAP_READ`, *parent_vmar* must be of type `ZX_OBJ_TYPE_VMAR` and have `ZX_RIGHT_READ`.
///
/// If *options* & `ZX_VM_CAN_MAP_WRITE`, *parent_vmar* must be of type `ZX_OBJ_TYPE_VMAR` and have `ZX_RIGHT_WRITE`.
///
/// If *options* & `ZX_VM_CAN_MAP_EXECUTE`, *parent_vmar* must be of type `ZX_OBJ_TYPE_VMAR` and have `ZX_RIGHT_EXECUTE`.
///
/// ## Return value
///
/// `zx_vmar_allocate()` returns `ZX_OK`, the absolute base address of the
/// subregion (via *child_addr*), and a handle to the new subregion (via
/// *child_vmar*) on success. The base address will be page-aligned and non-zero.
/// In the event of failure, a negative error value is returned.
///
/// ## Errors
///
/// `ZX_ERR_BAD_HANDLE` *parent_vmar* is not a valid handle.
///
/// `ZX_ERR_WRONG_TYPE` *parent_vmar* is not a VMAR handle.
///
/// `ZX_ERR_BAD_STATE` *parent_vmar* refers to a destroyed VMAR.
///
/// `ZX_ERR_INVALID_ARGS` for any of the following:
/// - *child_vmar* or *child_addr* are not valid,
/// - *offset* is non-zero when `ZX_VM_SPECIFIC` or `ZX_VM_OFFSET_IS_UPPER_LIMIT` is not given.
/// - `ZX_VM_OFFSET_IS_UPPER_LIMIT` is specified together with `ZX_VM_SPECIFIC`.
/// - *offset* and *size* describe an unsatisfiable allocation due to exceeding the region bounds
/// - *offset* or *size* is not page-aligned, or *size* is 0.
///
/// `ZX_ERR_NO_MEMORY` This may be due to the following:
///
/// * A free address range of the requested size is not available within
/// *parent_vmar*.
/// * The system is out of memory resources.
///
/// `ZX_ERR_ACCESS_DENIED` Insufficient privileges to make the requested allocation.
///
/// ## Notes
///
/// ### Deallocation
///
/// The address space occupied by a VMAR will remain allocated (within its
/// parent VMAR) until the VMAR is destroyed by calling [`zx_vmar_destroy()`].
///
/// Note that just closing the VMAR's handle does not deallocate the address
/// space occupied by the VMAR.
///
/// ### The COMPACT flag
///
/// The kernel interprets this flag as a request to reduce sprawl in allocations.
/// While this does not necessitate reducing the absolute entropy of the allocated
/// addresses, there will potentially be a very high correlation between allocations.
/// This is a trade-off that the developer can make to increase locality of
/// allocations and reduce the number of page tables necessary, if they are willing
/// to have certain addresses be more correlated.
///
/// ## See also
///
/// - [`zx_vmar_destroy()`]
/// - [`zx_vmar_map()`]
/// - [`zx_vmar_protect()`]
/// - [`zx_vmar_unmap()`]
///
/// [`zx_vmar_destroy()`]: vmar_destroy.md
/// [`zx_vmar_map()`]: vmar_map.md
/// [`zx_vmar_protect()`]: vmar_protect.md
/// [`zx_vmar_unmap()`]: vmar_unmap.md
strict Allocate(resource struct {
parent_vmar Handle:VMAR;
options VmOption;
offset usize64;
size usize64;
}) -> (resource struct {
child_vmar Handle:VMAR;
child_addr Vaddr;
}) error Status;
// TODO(https://fxbug.dev/42107929): handle No rights required?
/// ## Summary
///
/// Destroy a virtual memory address region.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vmar_destroy(zx_handle_t handle);
/// ```
///
/// ## Description
///
/// `zx_vmar_destroy()` unmaps all mappings within the given region, and destroys
/// all sub-regions of the region. Note that this operation is logically recursive.
///
/// This operation does not close *handle*. Any outstanding handles to this
/// VMAR will remain valid handles, but all VMAR operations on them will fail.
///
/// The root VMAR, as obtained by `zx_process_create()`, cannot be destroyed.
///
/// ## Rights
///
/// TODO(https://fxbug.dev/42107318)
///
/// ## Return value
///
/// `zx_vmar_destroy()` returns `ZX_OK` on success.
///
/// ## Errors
///
/// `ZX_ERR_ACCESS_DENIED` *handle* does not have `ZX_RIGHT_OP_CHILDREN`.
///
/// `ZX_ERR_BAD_HANDLE` *handle* is not a valid handle.
///
/// `ZX_ERR_WRONG_TYPE` *handle* is not a VMAR handle.
///
/// `ZX_ERR_BAD_STATE` This region is already destroyed.
///
/// `ZX_ERR_NOT_SUPPORTED` *handle* is a root VMAR.
///
/// ## Notes
///
/// ## See also
///
/// - [`zx_vmar_allocate()`]
/// - [`zx_vmar_map()`]
/// - [`zx_vmar_protect()`]
/// - [`zx_vmar_unmap()`]
///
/// [`zx_vmar_allocate()`]: vmar_allocate.md
/// [`zx_vmar_map()`]: vmar_map.md
/// [`zx_vmar_protect()`]: vmar_protect.md
/// [`zx_vmar_unmap()`]: vmar_unmap.md
strict Destroy(resource struct {
handle Handle:VMAR;
}) -> () error Status;
// TODO(https://fxbug.dev/42107318): TODO handle and vmo and options must all match, and options can't specify them.
/// ## Summary
///
/// Add a memory mapping.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vmar_map(zx_handle_t handle,
/// zx_vm_option_t options,
/// size_t vmar_offset,
/// zx_handle_t vmo,
/// uint64_t vmo_offset,
/// size_t len,
/// zx_vaddr_t* mapped_addr);
/// ```
///
/// ## Description
///
/// Maps the given VMO into the given virtual memory address region. The mapping
/// retains a reference to the underlying virtual memory object, which means
/// closing the VMO handle does not remove the mapping added by this function.
///
/// *options* is a bit vector of the following:
///
/// - `ZX_VM_SPECIFIC` Use the *vmar_offset* to place the mapping, invalid if
/// *handle* does not have the `ZX_VM_CAN_MAP_SPECIFIC` permission.
/// *vmar_offset* is an offset relative to the base address of the given VMAR.
/// It is an error to specify a range that overlaps with another VMAR or mapping.
/// - `ZX_VM_SPECIFIC_OVERWRITE` Same as `ZX_VM_SPECIFIC`, but can
/// overlap another mapping. It is still an error to partially-overlap another VMAR.
/// If the range meets these requirements, it will atomically (with respect to all
/// other map/unmap/protect operations) replace existing mappings in the range
/// specified by *vmar_offset* and *len*. If that range partially overlaps any
/// mappings, then the portions of those mappings outside the range will remain mapped.
/// - `ZX_VM_OFFSET_IS_UPPER_LIMIT` Interpret the *vmar_offset* as an upper limit
/// to constrain the selection of the offset by the kernel, invalid if *handle*
/// does not have the `ZX_VM_CAN_MAP_SPECIFIC` permission. The resulting mapping
/// will have an offset + *len* that is <= *vmar_offset*. This option cannot be
/// specified if `ZX_VM_SPECIFIC` or `ZX_VM_SPECIFIC_OVERWRITE` is used.
/// - `ZX_VM_PERM_READ` Map *vmo* as readable. It is an error if *handle*
/// does not have `ZX_VM_CAN_MAP_READ` permissions, the *handle* does
/// not have the `ZX_RIGHT_READ` right, or the *vmo* handle does not have the
/// `ZX_RIGHT_READ` right.
/// - `ZX_VM_PERM_WRITE` Map *vmo* as writable. It is an error if *handle*
/// does not have `ZX_VM_CAN_MAP_WRITE` permissions, the *handle* does
/// not have the `ZX_RIGHT_WRITE` right, the *vmo* handle does not have the
/// `ZX_RIGHT_WRITE` right, or *options* does not specify `ZX_VM_PERM_READ`.
/// - `ZX_VM_PERM_EXECUTE` Map *vmo* as executable. It is an error if *handle*
/// does not have `ZX_VM_CAN_MAP_EXECUTE` permissions, the *handle* handle does
/// not have the `ZX_RIGHT_EXECUTE` right, the *vmo* handle does not have the
/// `ZX_RIGHT_EXECUTE` right, or *options* does not specify `ZX_VM_PERM_READ`.
/// - `ZX_VM_MAP_RANGE` Immediately page into the new mapping all backed
/// regions of the VMO. This cannot be specified if
/// `ZX_VM_SPECIFIC_OVERWRITE` is used.
/// - `ZX_VM_ALLOW_FAULTS` Required if it would be possible for the created
/// mapping to generate faults. In particular, it is required if *vmo* is resizable,
/// if *vmo* is non-resizable but the mapping extends past the end of *vmo*, if
/// *vmo* is discardable, or if *vmo* was created from [`zx_pager_create_vmo()`].
/// - `ZX_VM_PERM_READ_IF_XOM_UNSUPPORTED` Map *vmo* as readable if the system does
/// not support mapping execute-only pages. If the system can map execute-only
/// this flag is ignored.
/// - `ZX_VM_REQUIRE_NON_RESIZABLE` Fail if *vmo* is resizable.
///
/// *vmar_offset* must be 0 if *options* does not have `ZX_VM_SPECIFIC`,
/// `ZX_VM_SPECIFIC_OVERWRITE` or `ZX_VM_OFFSET_IS_UPPER_LIMIT` set.
/// `ZX_VM_OFFSET_IS_UPPER_LIMIT` serves to constrain the selection range, and
/// otherwise behaves similarly to the case where neither `ZX_VM_SPECIFIC` nor
/// `ZX_VM_SPECIFIC_OVERWRITE` are set, with the mapping being assigned an offset
/// at random by the kernel (with an allocator determined by policy set on the
/// target VMAR).
///
/// *len* must be non-zero and page-aligned.
///
/// In addition one of the following power-of-two alignment flags can added:
///
/// - `ZX_VM_ALIGN_1KB` aligns *child_addr* to a power-of-2 at least 1K bytes.
/// - `ZX_VM_ALIGN_2KB` aligns *child_addr* to a power-of-2 at least 2K bytes.
/// - `ZX_VM_ALIGN_4KB` aligns *child_addr* to a power-of-2 at least 4K bytes.
/// - `ZX_VM_ALIGN_8KB` aligns *child_addr* to a power-of-2 at least 8K bytes.
/// and continues up to
/// - `ZX_VM_ALIGN_4GB` aligns *child_addr* to a power-of-2 at least 4G bytes.
///
/// Using `ZX_VM_ALIGN` flags with `ZX_VM_SPECIFIC` will fail if the vmar
/// base address + *vmo_offset* are not aligned to the requested value.
///
/// ## Rights
///
/// *handle* must be of type `ZX_OBJ_TYPE_VMAR`.
///
/// *vmo* must be of type `ZX_OBJ_TYPE_VMO`.
///
/// ## Return value
///
/// `zx_vmar_map()` returns `ZX_OK` and the absolute base address of the
/// mapping (via *mapped_addr*) on success. The base address will be page-aligned
/// and non-zero. In the event of failure, a negative error value is returned.
///
/// ## Errors
///
/// `ZX_ERR_BAD_HANDLE` *handle* or *vmo* is not a valid handle.
///
/// `ZX_ERR_WRONG_TYPE` *handle* or *vmo* is not a VMAR or VMO handle, respectively.
///
/// `ZX_ERR_BAD_STATE` *handle* refers to a destroyed VMAR.
///
/// `ZX_ERR_INVALID_ARGS` for any of the following:
/// - *mapped_addr* or *options* is not valid.
/// - *vmar_offset* is non-zero when none of `ZX_VM_SPECIFIC`, `ZX_VM_SPECIFIC_OVERWRITE` or
/// `ZX_VM_OFFSET_IS_UPPER_LIMIT` is specified.
/// - `ZX_VM_SPECIFIC_OVERWRITE` and `ZX_VM_MAP_RANGE` are both specified.
/// - `ZX_VM_OFFSET_IS_UPPER_LIMIT` is specified together with either `ZX_VM_SPECIFIC`
/// or `ZX_VM_SPECIFIC_OVERWRITE`.
/// - *vmar_offset* and *len* describe an unsatisfiable allocation due to exceeding the region bounds.
/// - *vmar_offset* or *vmo_offset* is not page-aligned.
/// - *len* is 0 or not page-aligned.
///
/// `ZX_ERR_ALREADY_EXISTS` `ZX_VM_SPECIFIC` has been specified without
/// `ZX_VM_SPECIFIC_OVERWRITE`, and the requested range overlaps with another mapping.
///
/// `ZX_ERR_NO_RESOURCES` If a spot could not be found in the VMAR to create the mapping.
///
/// `ZX_ERR_ACCESS_DENIED` Insufficient privileges to make the requested mapping.
///
/// `ZX_ERR_NOT_SUPPORTED` If the vmo is resizable, discardable, or backed by a pager but
/// `ZX_VM_ALLOW_FAULTS` is not set.
///
/// `ZX_ERR_NOT_SUPPORTED` If the vmo is resizable and `ZX_VM_REQUIRE_NON_RESIZABLE` is set.
///
/// `ZX_ERR_BUFFER_TOO_SMALL` The VMO is not resizable and the mapping extends past the end
/// of the VMO but `ZX_VM_ALLOW_FAULTS` is not set.
///
/// `ZX_ERR_NO_MEMORY` Failure due to lack of memory.
/// There is no good way for userspace to handle this (unlikely) error.
/// In a future build this error will no longer occur.
///
/// `ZX_ERR_OUT_OF_RANGE` `vmo_offset + ROUNDUP(len, PAGE_SIZE)` overflows.
///
/// ## Notes
///
/// The VMO that backs a memory mapping can be resized to a smaller size. This can cause the
/// thread is reading or writing to the VMAR region to fault. To avoid this hazard, services
/// that receive VMOs from clients should use `ZX_VM_REQUIRE_NON_RESIZABLE` when mapping
/// the VMO.
///
/// ## See also
///
/// - [`zx_vmar_allocate()`]
/// - [`zx_vmar_destroy()`]
/// - [`zx_vmar_protect()`]
/// - [`zx_vmar_unmap()`]
///
/// [`zx_pager_create_vmo()`]: pager_create_vmo.md
/// [`zx_vmar_allocate()`]: vmar_allocate.md
/// [`zx_vmar_destroy()`]: vmar_destroy.md
/// [`zx_vmar_protect()`]: vmar_protect.md
/// [`zx_vmar_unmap()`]: vmar_unmap.md
strict Map(resource struct {
handle Handle:VMAR;
options VmOption;
vmar_offset usize64;
vmo Handle:VMO;
vmo_offset uint64;
len usize64;
}) -> (struct {
mapped_addr Vaddr;
}) error Status;
// TODO(https://fxbug.dev/42107929): handle No rights required?
/// ## Summary
///
/// Unmap virtual memory pages.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vmar_unmap(zx_handle_t handle, zx_vaddr_t addr, size_t len);
/// ```
///
/// ## Description
///
/// `zx_vmar_unmap()` unmaps all VMO mappings and destroys (as if [`zx_vmar_destroy()`]
/// were called) all sub-regions within the absolute range including *addr* and ending
/// before exclusively at `addr + len`. Any sub-region that is in the range must
/// be fully in the range (i.e. partial overlaps are an error). If a mapping is
/// only partially in the range, the mapping is split and the requested portion is
/// unmapped.
///
/// *len* must be page-aligned.
///
/// ## Rights
///
/// TODO(https://fxbug.dev/42107318)
///
/// ## Return value
///
/// `zx_vmar_unmap()` returns `ZX_OK` on success.
///
/// ## Errors
///
/// `ZX_ERR_BAD_HANDLE` *handle* is not a valid handle.
///
/// `ZX_ERR_WRONG_TYPE` *handle* is not a VMAR handle.
///
/// `ZX_ERR_INVALID_ARGS` *addr* is not page-aligned, *len* is 0 or not page-aligned,
/// or the requested range partially overlaps a sub-region, or the requested range overlapped
/// a sub-region and *handle* did not have `ZX_RIGHT_OP_CHILDREN`.
///
/// `ZX_ERR_BAD_STATE` *handle* refers to a destroyed handle.
///
/// `ZX_ERR_NOT_FOUND` Could not find the requested mapping.
///
/// ## Notes
///
/// ## See also
///
/// - [`zx_vmar_allocate()`]
/// - [`zx_vmar_destroy()`]
/// - [`zx_vmar_map()`]
/// - [`zx_vmar_protect()`]
///
/// [`zx_vmar_allocate()`]: vmar_allocate.md
/// [`zx_vmar_destroy()`]: vmar_destroy.md
/// [`zx_vmar_map()`]: vmar_map.md
/// [`zx_vmar_protect()`]: vmar_protect.md
strict Unmap(resource struct {
handle Handle:VMAR;
addr Vaddr;
len usize64;
}) -> () error Status;
/// ## Summary
///
/// Set protection of virtual memory pages.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vmar_protect(zx_handle_t handle,
/// zx_vm_option_t options,
/// zx_vaddr_t addr,
/// size_t len);
/// ```
///
/// ## Description
///
/// `zx_vmar_protect()` alters the access protections for the memory mappings
/// in the range of *len* bytes starting from *addr*. The *options* argument should
/// be a bitwise-or of one or more of the following:
///
/// - `ZX_VM_PERM_READ` Map as readable. It is an error if *handle*
/// does not have `ZX_VM_CAN_MAP_READ` permissions or *handle* does
/// not have the `ZX_RIGHT_READ` right. It is also an error if the VMO handle
/// used to create the mapping did not have the `ZX_RIGHT_READ` right.
/// - `ZX_VM_PERM_WRITE` Map as writable. It is an error if *handle*
/// does not have `ZX_VM_CAN_MAP_WRITE` permissions or *handle* does
/// not have the `ZX_RIGHT_WRITE` right. It is also an error if the VMO handle
/// used to create the mapping did not have the `ZX_RIGHT_WRITE` right.
/// - `ZX_VM_PERM_EXECUTE` Map as executable. It is an error if *handle*
/// does not have `ZX_VM_CAN_MAP_EXECUTE` permissions or *handle* does
/// not have the `ZX_RIGHT_EXECUTE` right. It is also an error if the VMO handle
/// used to create the mapping did not have the `ZX_RIGHT_EXECUTE` right.
/// - `ZX_VM_PERM_READ_IF_XOM_UNSUPPORTED` Map as readable if the system does
/// not support mapping execute-only pages. If the system can map execute-only
/// this flag is ignored.
///
/// For any mappings in sub-regions in the requested range, their access permissions must either
/// be reduced, or left unchanged, by the requested change.
///
/// *len* must be page-aligned.
///
/// ## Rights
///
/// If *options* & `ZX_VM_PERM_READ`, *handle* must be of type `ZX_OBJ_TYPE_VMAR` and have `ZX_RIGHT_READ`.
///
/// If *options* & `ZX_VM_PERM_WRITE`, *handle* must be of type `ZX_OBJ_TYPE_VMAR` and have `ZX_RIGHT_WRITE`.
///
/// If *options* & `ZX_VM_PERM_EXECUTE`, *handle* must be of type `ZX_OBJ_TYPE_VMAR` and have `ZX_RIGHT_EXECUTE`.
///
/// ## Return value
///
/// `zx_vmar_protect()` returns `ZX_OK` on success.
///
/// ## Errors
///
/// `ZX_ERR_BAD_HANDLE` *handle* is not a valid handle.
///
/// `ZX_ERR_WRONG_TYPE` *handle* is not a VMAR handle.
///
/// `ZX_ERR_INVALID_ARGS` *prot_flags* is an unsupported combination of flags
/// (e.g., `ZX_VM_PERM_WRITE` but not `ZX_VM_PERM_READ`), *addr* is
/// not page-aligned, *len* is 0, or some subrange of the requested range is
/// occupied by a subregion and *handle* did not have `ZX_RIGHT_OP_CHILDREN`.
///
/// `ZX_ERR_NOT_FOUND` Some subrange of the requested range is not mapped.
///
/// `ZX_ERR_ACCESS_DENIED` *handle* does not have the proper rights for the
/// requested change, the original VMO handle used to create the mapping did not
/// have the rights for the requested change, or the VMAR itself does not allow
/// the requested change, or there is a mapping in a sub-region that would have
/// its mapping permissions increased.
///
/// `ZX_ERR_NO_MEMORY` Failure due to lack of memory.
/// There is no good way for userspace to handle this (unlikely) error.
/// In a future build this error will no longer occur.
///
/// ## Notes
///
/// For failures other than `ZX_ERR_NO_MEMORY`, all access permissions in the range
/// will have been left unchanged.
///
/// ## See also
///
/// - [`zx_vmar_allocate()`]
/// - [`zx_vmar_destroy()`]
/// - [`zx_vmar_map()`]
/// - [`zx_vmar_unmap()`]
///
/// [`zx_vmar_allocate()`]: vmar_allocate.md
/// [`zx_vmar_destroy()`]: vmar_destroy.md
/// [`zx_vmar_map()`]: vmar_map.md
/// [`zx_vmar_unmap()`]: vmar_unmap.md
strict Protect(resource struct {
handle Handle:VMAR;
options VmOption;
addr Vaddr;
len usize64;
}) -> () error Status;
/// ## Summary
///
/// Perform an operation on VMOs mapped into this VMAR.
///
/// ## Declaration
///
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vmar_op_range(zx_handle_t handle,
/// uint32_t op,
/// zx_vaddr_t address,
/// size_t size,
/// void* buffer,
/// size_t buffer_size);
/// ```
///
/// ## Description
///
/// `zx_vmar_op_range()` performs operation *op* on VMOs mapped in the range *address* to
/// *address*+*size*.
///
/// *address* and *size* must fall entirely within this VMAR, and must meet the alignment requirements
/// specified for the corresponding VMO *op* (if there is one) by [`zx_vmo_op_range()`].
///
/// *buffer* and *buffer_size* are currently unused, and must be empty.
///
/// The supported operations are:
///
/// `ZX_VMAR_OP_COMMIT` - Requires that *handle*, and the VMO handles used to create any affected
/// mappings, have the `ZX_RIGHT_WRITE` right and that the address range must not have any child VMARs.
/// The operation's semantics are otherwise as described by
/// [`zx_vmo_op_range()`](/docs/reference/syscalls/vmo_op_range.md) `ZX_VMO_OP_COMMIT`.
///
/// `ZX_VMO_OP_DECOMMIT` - Deprecated. Use `ZX_VMAR_OP_DECOMMIT` instead.
///
/// `ZX_VMAR_OP_DECOMMIT` - Requires that *handle*, and the VMO handles used to create any affected
/// mappings, have the `ZX_RIGHT_WRITE` right and that the address range must not have any child VMARs.
/// The operation's semantics are otherwise as described by
/// [`zx_vmo_op_range()`](/docs/reference/syscalls/vmo_op_range.md) `ZX_VMO_OP_DECOMMIT`.
///
/// `ZX_VMAR_OP_MAP_RANGE` - Populates entries in the CPU page tables (or architectural equivalent)
/// for committed pages in the given range. Entries for uncommitted pages in the range are not
/// populated. Skips entries that already exist for any page in the range.
///
/// `ZX_VMAR_OP_DONT_NEED` - Hints that pages in the specified range are not needed anymore and should
/// be considered for memory reclamation. Intended to be used on mappings for VMOs created with
/// [`zx_pager_create_vmo()`](/docs/reference/syscalls/pager_create_vmo.md); trivially succeeds for
/// mappings for other VMO types.
///
/// Please refer to [`zx_vmo_op_range()`](/docs/reference/syscalls/vmo_op_range.md)
/// `ZX_VMO_OP_DONT_NEED` for more details.
///
/// `ZX_VMAR_OP_ALWAYS_NEED` - Hints that pages in the specified range are important and should be
/// protected from memory reclamation. Intended to be used on mappings for VMOs created with
/// [`zx_pager_create_vmo()`](/docs/reference/syscalls/pager_create_vmo.md); trivially succeeds for
/// mappings for other VMO types.
///
/// Please refer to [`zx_vmo_op_range()`](/docs/reference/syscalls/vmo_op_range.md)
/// `ZX_VMO_OP_ALWAYS_NEED` for more details.
///
/// ## Rights
///
/// If *op* is `ZX_VMAR_OP_DECOMMIT`, *handle* must have `ZX_RIGHT_WRITE`.
///
/// If *op* is `ZX_VMAR_OP_COMMIT`, *handle* must have `ZX_RIGHT_WRITE`.
///
/// ## Return value
///
/// `zx_vmar_op_range()` returns `ZX_OK` on success. In the event of failure, a negative error value
/// is returned.
///
/// ## Errors
///
/// `ZX_ERR_ACCESS_DENIED` *handle* does not have the proper rights for the requested change, or the
/// original VMO handle used to created one of the affected mappings did not have the rights for the
/// requested change, or the VMAR itself did not allow the requested change.
///
/// `ZX_ERR_BAD_HANDLE` *handle* is not a valid handle.
///
/// `ZX_ERR_BAD_STATE` *handle* is not a live VMAR, or the range specified by *address* and *size*
/// spans unmapped regions.
///
/// `ZX_ERR_INVALID_ARGS` Returned for any of the following reasons:
///
/// - *buffer* is non-null.
/// - *buffer_size* is non-zero.
/// - *size* is zero.
/// - *address* was not page-aligned.
/// - *op* is not a valid operation.
/// - *op* was one of `ZX_VMAR_OP_COMMIT` or `ZX_VMAR_OP_DECOMMIT` and the requested range
/// had subregions.
/// - the requested range overlapped a sub-region and *handle* did not have
/// `ZX_RIGHT_OP_CHILDREN`.
///
/// `ZX_ERR_NOT_SUPPORTED` *op* was not `ZX_VMO_OP_DECOMMIT`, or one or more mapped VMOs do not
/// support the requested *op*.
///
/// `ZX_ERR_OUT_OF_RANGE` The range specified by *address* and *size* is not wholly within the VM
/// address range specified by *handle*.
///
/// `ZX_ERR_WRONG_TYPE` *handle* is not a VMAR handle.
///
/// ## See also
///
/// - [`zx_vmar_map()`]
/// - [`zx_vmar_unmap()`]
/// - [`zx_vmo_op_range()`]
///
/// [`zx_pager_create_vmo()`]: pager_create_vmo.md
/// [`zx_vmar_map()`]: vmar_map.md
/// [`zx_vmar_unmap()`]: vmar_unmap.md
/// [`zx_vmo_op_range()`]: vmo_op_range.md
strict OpRange(resource struct {
handle Handle:VMAR;
op uint32;
address Vaddr;
size usize64;
@inout
@voidptr
buffer vector<byte>:MAX;
}) -> () error Status;
/// ## Summary
///
/// Map the memory regions attached to an IOBuffer. This call has
/// similar semantics to `zx_vmar_map`, however, mapping subsets of regions
/// is not supported.
///
/// ## Declaration
/// ```c
/// #include <zircon/syscalls.h>
///
/// zx_status_t zx_vmar_map_iob(zx_handle_t handle,
/// zx_vm_option_t options,
/// size_t vmar_offset,
/// zx_handle_t iob_ep,
/// uint32_t region_index,
/// size_t region_len,
/// zx_vaddr_t* addr_out);
/// ```
///
/// ## Description
///
/// Maps the given IOBuffer region into the given virtual memory
/// address region. Mapping a region retains a reference to the mapped
/// region, which means closing the endpoint that mapped the region does not
/// remove the mapping added by this function.
///
/// *options* is equivalent to the *options* parameter of `zx_vmar_map`
///
/// *vmar_offset* is equivalent to the *vmar_offset* parameter of `zx_vmar_map`.
///
/// *ep* is the endpoint containing the region to map as created in
/// `zx_iob_create`.
///
/// *region_index* is the index of the memory region to map.
///
/// *region_offset* is equivalent to the *vmo_offset* parameter of `zx_vmar_map`.
///
/// *region_len* is equivalent to the *len* parameter of `zx_vmar_map`. It
/// must by non-zero and page-aligned
///
/// ## Return value
///
/// `zx_vmar_map_iob()` returns `ZX_OK` and the absolute base address of the
/// mapping (via *addr_out*) on success. The base address will be page-aligned
/// and non-zero. In the event of failure, a negative error value is returned.
///
/// ## Errors
///
/// `ZX_ERR_BAD_HANDLE` *handle* or *iob_ep* is not a valid handle.
///
/// `ZX_ERR_WRONG_TYPE` *handle* or *iob_ep* is not a VMAR or IOB handle, respectively.
///
/// `ZX_ERR_BAD_STATE` *handle* refers to a destroyed VMAR.
///
/// `ZX_ERR_INVALID_ARGS` for any of the following:
/// - *mapped_addr* or *options* is not valid.
/// - *vmar_offset* is non-zero when none of `ZX_VM_SPECIFIC`, `ZX_VM_SPECIFIC_OVERWRITE` or
/// `ZX_VM_OFFSET_IS_UPPER_LIMIT` is specified.
/// - `ZX_VM_SPECIFIC_OVERWRITE` and `ZX_VM_MAP_RANGE` are both specified.
/// - `ZX_VM_OFFSET_IS_UPPER_LIMIT` is specified together with either `ZX_VM_SPECIFIC`
/// or `ZX_VM_SPECIFIC_OVERWRITE`.
/// - *vmar_offset* and *len* describe an unsatisfiable allocation due to exceeding the region bounds.
/// - *vmar_offset* or *region_offset* is not page-aligned.
/// - *region_len* is 0 or not page-aligned.
///
/// `ZX_ERR_ALREADY_EXISTS` `ZX_VM_SPECIFIC` has been specified without
/// `ZX_VM_SPECIFIC_OVERWRITE`, and the requested range overlaps with another mapping.
///
/// `ZX_ERR_NO_RESOURCES` If a spot could not be found in the VMAR to create the mapping.
///
/// `ZX_ERR_ACCESS_DENIED` Insufficient privileges to make the requested mapping.
///
/// `ZX_ERR_NOT_SUPPORTED` If the region is resizable, discardable, or backed by a pager but
/// `ZX_VM_ALLOW_FAULTS` is not set.
///
/// `ZX_ERR_BUFFER_TOO_SMALL` The region is not resizable and the mapping extends past the end
/// of the region but `ZX_VM_ALLOW_FAULTS` is not set.
///
/// `ZX_ERR_NO_MEMORY` Failure due to lack of memory.
/// There is no good way for userspace to handle this (unlikely) error.
/// In a future build this error will no longer occur.
///
/// `ZX_ERR_OUT_OF_RANGE` for any of the following:
/// - `region_offset + ROUNDUP(len, PAGE_SIZE)` overflows.
/// - *region_index* is not valid for the provided IOB
///
///
/// ## Notes
///
/// ### VMAR Operations
///
/// Mapped regions generally support VMAR operations, such as `zx_vmar_protect`,
/// `zx_vmar_op_range`, `zx_vmar_destroy`. A region's access discipline may modify
/// or restrict these operations as described in the discipline spec.
///
/// ## See also
///
/// - [`zx_vmar_map()`]
/// - [`zx_iob_create()`]
///
/// [`zx_iob_create()`]: iob_create.md
/// [`zx_vmar_map()`]: vmar_map.md
strict MapIob(resource struct {
handle Handle:VMAR;
options VmOption;
vmar_offset usize64;
ep Handle;
region_index uint32;
region_offset uint64;
region_length usize64;
}) -> (resource struct {
mapped_addr Vaddr;
}) error Status;
};