zxvmo_create_child

摘要

创建虚拟机对象 (VMO) 的子对象。

声明

#include <zircon/syscalls.h>

zx_status_t zx_vmo_create_child(zx_handle_t handle,
                                uint32_t options,
                                uint64_t offset,
                                uint64_t size,
                                zx_handle_t* out);

说明

zx_vmo_create_child() 会创建一个新的 虚拟内存 对象 (VMO),它是现有 VMO 的子对象。语义的行为取决于子对象的类型。

成功后,系统会返回一个句柄,表示具有请求大小的对象。

options 必须包含以下标志之一,以指定子对象的类型:

  • ZX_VMO_CHILD_SNAPSHOT - 创建一个行为类似于执行了预先复制的子对象。发生写入时,父对象和子对象都会执行延迟复制。延迟复制允许子对象和父对象彼此分离。从父 VMO 大小范围之外的范围进行的任何读取都包含零,而写入则会分配新的零填充页面。使用 ZX_VMO_CHILD_NO_WRITE 创建且未使用 ZX_VMO_CHILD_RESIZABLE 创建时,会创建不可变的 VMO。

以下对象不支持此标志:

  • 具有固定区域的 VMO。
  • 使用 zx_vmo_create_physical()zx_vmo_create_contiguous() 创建或派生的 VMO
  • 由用户分页器支持的 VMO。 如需了解 VMO 系统调用与子对象的互动,请参阅 备注

  • ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE - 创建一个行为至少具有写入时复制语义的子对象。对子对象执行的任何写入操作都会从父对象中引入页面的副本,之后其内容可能会与父对象不同。在页面被写入和复制之前,允许读取,但如果父对象执行写入,则不保证返回更改的值。 此标志不能用于使用 zx_vmo_create_physical()zx_vmo_create_contiguous() 或此类 VMO 的后代创建的 VMO。 如需了解 VMO 系统调用与子对象的互动,请参阅 备注

  • ZX_VMO_CHILD_SNAPSHOT_MODIFIED - 创建一个行为类似于对父对象中任何未由分页器支持的页面执行了预先复制的子对象,即已由分页器支持的 VMO 的子对象修改的页面。分页器支持的页面将至少具有写入时复制语义。此 标志不能用于使用 zx_vmo_create_physical()zx_vmo_create_contiguous()、 包含固定页面的 VMO 或此类 VMO 的后代创建的 VMO。对于使用 SNAPSHOT_AT_LEAST_ON_WRITE 创建的任何具有非切片子对象或不是分页器支持的 VMO 的子对象的 VMO,也不支持此标志。 如需了解 VMO 系统调用与子对象的互动,请参阅 备注

  • ZX_VMO_CHILD_REFERENCE - 创建对 VMO 的引用。对引用 VMO 的所有操作的行为都与对父对象执行的操作相同。引用始终跨越整个父对象,并且 offsetsize 必须为 0。当用户想要使用 ZX_VMO_ZERO_CHILDREN 信号跟踪对 VMO 的未完成引用时,此功能非常有用。如需详细了解此信号,请参阅 备注。 此标志不能用于使用 zx_vmo_create_physical()zx_vmo_create_contiguous() 或此类 VMO 的后代创建的 VMO。

  • ZX_VMO_CHILD_SLICE - 创建一个切片,该切片可以直接读取/写入父对象的一部分。切片与引用的不同之处在于,它仅允许访问父 VMO 的子范围 ,并且受不同父 VMO 类型的支持:ZX_VMO_CHILD_SLICE 可用于使用 zx_vmo_create_physical()zx_vmo_create_contiguous() 创建的 VMO 及其 后代。此标志不能用于使用 ZX_VMO_RESIZABLE 选项创建的 VMO。

此外,options 可以包含零个或多个以下标志,以进一步指定子对象的行为:

  • ZX_VMO_CHILD_RESIZABLE - 创建可调整大小的子 VMO。这与 ZX_VMO_CHILD_SLICE不兼容。仅当父句柄具有 ZX_RIGHT_RESIZE 时,此标志才与 ZX_VMO_CHILD_REFERENCE 兼容。

  • ZX_VMO_CHILD_NO_WRITE - 创建无法写入的子对象。这与 ZX_VMO_CHILD_RESIZABLE 不兼容。

offset 必须与页面对齐。

offset + size 不得超出 64 位无符号值的范围。

偏移量和大小都可以从原始 VMO 的大小开始或超出原始 VMO 的大小。

VMO 的大小将向上舍入到下一个页面大小边界。

VMO 的内容大小将初始化为给定的(未舍入)大小。 使用 zx_object_get_property()ZX_PROP_VMO_CONTENT_SIZE 读取 VMO 的内容大小。使用 zx_object_set_property()ZX_PROP_VMO_CONTENT_SIZE 设置 VMO 的内容大小,而无需 实际调整 VMO 的大小。

默认情况下,子句柄的权限与原始句柄的权限相同,但有一些例外情况。如需详细了解每项权限,请参阅 zx_vmo_create()

如果 options 包含 ZX_VMO_CHILD_RESIZABLE,则会添加 ZX_RIGHT_RESIZE

对于 ZX_VMO_CHILD_REFERENCEZX_VMO_CHILD_RESIZABLE 选项控制是否可以使用 out 中返回的引用句柄调整父 VMO 的大小。如果父 VMO 可调整大小,则无论是否存在 ZX_VMO_CHILD_RESIZABLE,引用都会看到父 VMO 的大小调整。不过,仅当父 VMO 可调整大小时,才支持 ZX_VMO_CHILD_RESIZABLE,也就是说,无法为不可调整大小的 VMO 创建可调整大小的引用。

在所有情况下,如果设置了 ZX_VMO_NO_WRITE,则会移除 ZX_RIGHT_WRITE

如果 optionsZX_VMO_CHILD_SNAPSHOTZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITEZX_VMO_CHILD_SNAPSHOT_MODIFIED,并且未设置 ZX_VMO_CHILD_NO_WRITE,则会添加 ZX_RIGHT_WRITE 并移除 ZX_RIGHT_EXECUTE

备注

创建子 VMO 会导致现有(源)VMO ZX_VMO_ZERO_CHILDREN 信号变为无效。只有在销毁最后一个子对象且这些子对象在地址空间中没有映射时,ZX_VMO_ZERO_CHILDREN 才会再次变为有效。

非切片子 VMO 将以以下方式与 VMO 系统调用互动:

  • 子对象上 zx_vmo_op_range() 的 COMMIT 模式会将页面提交到子对象中,这些页面 与父对象的相应页面具有相同的内容。如果这些页面由分页器提供,此操作也会在父对象中提交这些页面。否则,如果这些页面未在父对象中提交,则零填充页面将直接提交到子对象中,而不会影响父对象。
  • 不支持 zx_vmo_op_range() 的 DECOMMIT 模式。

权限

handle 必须为 ZX_OBJ_TYPE_VMO 类型,并且具有 ZX_RIGHT_DUPLICATEZX_RIGHT_READ

返回值

成功后,zx_vmo_create_child() 会返回 ZX_OK。如果失败,则会返回负错误值。

错误

ZX_ERR_BAD_TYPE 输入句柄不是 VMO。

ZX_ERR_ACCESS_DENIED 输入句柄没有足够的权限。

ZX_ERR_INVALID_ARGS out 是无效指针或 NULL,或者偏移量未与页面对齐,或者给出了不兼容的 options 组合。

ZX_ERR_OUT_OF_RANGE offset + size 过大。

ZX_ERR_NO_MEMORY 因内存不足而失败。 用户空间无法很好地处理此(不太可能发生的)错误。 在未来的版本中,此错误将不再发生。

ZX_ERR_BAD_STATE 无法创建 COW 子对象,因为 VMO 具有一些固定页面。

ZX_ERR_NOT_SUPPORTED 输入句柄是可舍弃的 VMO,或者输入句柄是可调整大小的 VMO,并且 options 包含 ZX_VMO_CHILD_SLICE

另请参阅