| // 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") |
| 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 |
| 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(fxbug.dev/32803): 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(fxbug.dev/32253) |
| /// |
| /// ## 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 |
| Destroy(resource struct { |
| handle Handle:VMAR; |
| }) -> () error Status; |
| |
| // TODO(fxbug.dev/32253): 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. |
| /// |
| /// *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_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 |
| 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(fxbug.dev/32803): 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(fxbug.dev/32253) |
| /// |
| /// ## 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 |
| 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 |
| 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 |
| OpRange(resource struct { |
| handle Handle:VMAR; |
| op uint32; |
| address Vaddr; |
| size usize64; |
| @inout |
| @voidptr |
| buffer vector<byte>:MAX; |
| }) -> () error Status; |
| }; |