摘要
创建分页器拥有的 VMO。
声明
#include <zircon/syscalls.h>
zx_status_t zx_pager_create_vmo(zx_handle_t pager,
uint32_t options,
zx_handle_t port,
uint64_t key,
uint64_t size,
zx_handle_t* out);
说明
创建归分页器对象所有的 VMO。size 将向上舍入为下一个页面大小边界,并且 options 必须为零或以下标志的组合:
ZX_VMO_RESIZABLE
- 如果 VMO 可以调整大小。
ZX_VMO_TRAP_DIRTY
- 是否应该由内核捕获对 VMO 中干净页的写入操作,并转发到分页器服务进行确认,然后再继续写入。
ZX_VMO_UNBOUNDED
,用于创建初始化为可能的最大大小的 VMO。不能与 ZX_VMO_RESIZABLE
结合使用。不使用传入的 size 参数,必须将其设置为 0。
成功后,返回的 VMO 具有与使用 zx_vmo_create()
创建的 VMO 相同的权限,并且对于 ZX_VMO_ZERO_CHILDREN
的行为也相同。在 VMO 上运行的系统调用需要一个显式标志来允许阻止向用户空间分页器服务的 IPC;除此之外,某个 VMO 是否归分页器所有不会影响系统调用的语义。
TODO(stevend):在更新克隆和取消提交后更新差异
当满足特定条件时,页面请求将传送到 port。这些数据包的 type 将设置为 ZX_PKT_TYPE_PAGE_REQUEST
,key 将设置为提供给 zx_pager_create_vmo()
的值。数据包的联合类型为 zx_packet_page_request_t
:
typedef struct zx_packet_page_request {
uint16_t command;
uint16_t flags;
uint32_t reserved0;
uint64_t offset;
uint64_t length;
uint64_t reserved1;
} zx_packet_page_request_t;
offset 和 length 始终页面对齐。flags 中未定义标志的任何位的值都未指定 - 目前尚未定义任何标志。数据包的触发器和含义取决于命令,该命令可以采用以下值之一:
ZX_PAGER_VMO_READ
:当应用访问寻呼机 VMO 中的非常驻页面时发送。分页器服务应使用 zx_pager_supply_pages()
填充已注册的 VMO 中的范围 [offset, offset + length)。提供页面是指对请求的隐式肯定确认。
ZX_PAGER_VMO_DIRTY
:当应用写入使用 ZX_VMO_TRAP_DIRTY
标志创建的分页器 VMO 中的常驻干净页时发送。分页器服务应通过 zx_pager_op_range()
ZX_PAGER_OP_DIRTY
确认范围 [偏移、偏移 + 长度] 是脏的,允许写入继续。
ZX_PAGER_VMO_COMPLETE
:当不再针对相应 VMO 发送分页器请求时发送,原因可能是 zx_pager_detach_vmo()
或没有对 VMO 的引用。
如果 pager 关闭,则不会再向 port 传送任何数据包(包括不包含 ZX_PAGER_VMO_COMPLETE
消息)。此外,未来的所有访问都将表现为调用了 zx_pager_detach_vmo()
。
权限
pager 必须为 ZX_OBJ_TYPE_PAGER
类型且具有 ZX_RIGHT_ATTACH_VMO
。
port 必须为 ZX_OBJ_TYPE_PORT
类型且具有 ZX_RIGHT_WRITE
。
返回值
zx_pager_create_vmo()
在成功时返回 ZX_OK,或者在失败时返回以下错误代码之一。
错误
ZX_ERR_INVALID_ARGS
out 是无效的指针或 NULL,options 包含不支持的标志组合,或者使用 ZX_VMO_UNBOUNDED
时的大小不是 0。
ZX_ERR_BAD_HANDLE
pager 或 port 不是有效句柄。
ZX_ERR_ACCESS_DENIED
pager 没有 ZX_RIGHT_ATTACH_VMO
,或者 port 没有 ZX_RIGHT_WRITE
。
ZX_ERR_WRONG_TYPE
pager 不是分页器句柄或 port 不是端口句柄。
ZX_ERR_OUT_OF_RANGE
请求的大小超出了 VMO 大小上限。
ZX_ERR_NO_MEMORY
因内存不足而失败。