摘要
创建虚拟机对象的子对象。
声明
#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 大小以外的范围的任何读取操作都包含零,而写入操作会分配新的零填充页面。以下版本不支持此标志:- 具有固定区域的 VMO。
- 使用
zx_vmo_create_physical()
或zx_vmo_create_contiguous()
或为其后代创建的 VMO - 由用户分页器支持的 VMO。如需了解与子级的 VMO 系统调用交互,请参阅说明。
启用 ZX_VMO_CHILD_NO_WRITE 选项且停用 ZX_VMO_CHILD_RESIZABLE 选项后,ZX_VMO_CHILD_SNAPSHOT 会创建不可变的 VMO。
ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE
- 创建一个在写入语义时行为至少为复制的子项。对子级执行的任何写入操作都会从父级获取页面的副本,之后其内容可能会与父级不同。在页面写入和复制之前,允许(但不能保证读取操作)在父项执行写入时返回更改的值。此标志不可用于使用zx_vmo_create_physical()
、zx_vmo_create_contiguous()
或此类 VMO 的后代创建的虚拟机。如需了解与子级的 VMO 系统调用交互,请参阅说明。
ZX_VMO_CHILD_SNAPSHOT_MODIFIED
- 创建一个子项,该子项的行为就像在父项中未由分页器支持的任何页面(即,由分页器支持的 VMO 的子项修改过)上执行的子项。由分页器支持的页面将至少具有写入时复制语义。此标志不可用于使用 zx_vmo_create_physical()
、zx_vmo_create_contiguous()
创建的虚拟机、包含固定页面的 VMO 或此类 VMO 的后代。使用 SNAPSHOT_AT_LEAST_ON_WRITE
创建且具有非切片子项或不是由分页器支持的 VMO 的子项的任何 VMO,也不支持此标志。如需了解与子级的 VMO 系统调用交互,请参阅说明。
ZX_VMO_CHILD_SLICE
- 创建对父项的某一部分拥有直接读写权限的切片。对切片 VMO 的所有操作都像在父项上完成一样。Slice 与父级 VMO 的重复句柄的不同之处在于,前者仅允许访问父级 VMO 的子范围,并允许使用ZX_VMO_ZERO_CHILDREN
信号。此标志可用于使用zx_vmo_create_physical()
或zx_vmo_create_contiguous()
及其后代创建的虚拟机 O。此标志不能与使用ZX_VMO_RESIZABLE
选项创建的虚拟机搭配使用。ZX_VMO_CHILD_REFERENCE
- 创建对 VMO 的引用。引用 VMO 上的所有操作都将像在父级上完成一样。引用始终跨越父级的整个范围,并且 offset 和 size 必须为 0。如果用户想要使用ZX_VMO_ZERO_CHILDREN
信号跟踪对 VMO 的未完成引用,这会非常有用。如需详细了解此信号,请参阅备注。此标志不可用于使用zx_vmo_create_physical()
、zx_vmo_create_contiguous()
或此类 VMO 的后代创建的虚拟机。
此外,options 可以包含以下零个或多个标志,以进一步指定子项的行为:
ZX_VMO_CHILD_RESIZABLE
- 创建可调整大小的子 VMO。这与ZX_VMO_CHILD_SLICE
不兼容。ZX_VMO_CHILD_NO_WRITE
- 创建一个无法写入的子项。这与ZX_VMO_CHILD_RESIZABLE
不兼容。
offset 必须与页面对齐。
offset + size 不得超过 64 位无符号值的范围。
偏移和大小都可能会在开始时或超出原始 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_REFERENCE
,ZX_VMO_CHILD_RESIZABLE
选项用于控制是否可以使用 out 中返回的引用句柄调整父级 VMO 的大小。如果父 VMO 可调整大小,则无论是否存在 ZX_VMO_CHILD_RESIZABLE
,引用都会看到父 VMO 的大小会调整。不过,仅当父级 VMO 可调整大小(即无法为不可调整大小的 VMO 创建可调整大小的引用)时,ZX_VMO_CHILD_RESIZABLE
才受支持。
在所有情况下,如果设置了 ZX_VMO_NO_WRITE
,则 ZX_RIGHT_WRITE
将被移除。
如果 options 为 ZX_VMO_CHILD_SNAPSHOT
、ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE
或 ZX_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 系统调用进行交互:
- 子级的
zx_vmo_op_range()
提交模式会将页面提交到子级,且这些页面的内容与其父级的对应页面相同。如果这些页面由分页器提供,则此操作也会在父级中提交这些页面。否则,如果这些页面未在父级提交,零填充的页面将直接提交到子级,而不会影响父级。 - 不支持
zx_vmo_op_range()
的 DECOMMIT 模式。
权限
handle 必须为 ZX_OBJ_TYPE_VMO
类型,具有 ZX_RIGHT_DUPLICATE
且具有 ZX_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
因内存不足而失败。
用户空间没有什么方法来处理此(不太可能)错误。在以后的 build 中,此错误不会再发生。
ZX_ERR_BAD_STATE
无法创建 COW 子账号,因为视频模版有一些固定的网页。
ZX_ERR_NOT_SUPPORTED
输入句柄是可舍弃的 VMO,或者输入句柄是可调整大小的 VMO,并且 options 包含 ZX_VMO_CHILD_SLICE
。
另请参阅
zx_vmar_map()
zx_vmo_create()
zx_vmo_get_size()
zx_vmo_op_range()
zx_vmo_read()
zx_vmo_set_size()
zx_vmo_write()