摘要
分配新的子区域。
声明
#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);
说明
在 parent_vmar 指定的 VMAR 中创建新的 VMAR。
options 是一个位向量,其中包含以下一项或多项:
ZX_VM_COMPACT向内核提示,新创建的子区域中的分配和映射应紧密相连。 如需相关讨论,请参阅下方的“备注”部分。ZX_VM_SPECIFIC使用 offset 来放置映射,如果 parent_vmar 没有ZX_VM_CAN_MAP_SPECIFIC权限,则此操作无效。offset 是相对于父区域基地址的偏移量。 指定与另一个 VMAR 或映射重叠的地址范围是错误的。ZX_VM_OFFSET_IS_UPPER_LIMIT将 offset 解释为上限 ,以限制内核对偏移量的选择;如果 parent_vmar 没有ZX_VM_CAN_MAP_SPECIFIC权限,则此操作无效。生成的映射的偏移量 + size 将 <= offset。如果使用ZX_VM_SPECIFIC,则无法指定此选项。ZX_VM_CAN_MAP_SPECIFIC新的 VMAR 可以使用ZX_VM_SPECIFIC创建子区域/映射。 如果父级没有ZX_VM_CAN_MAP_SPECIFIC权限,则不会出错。ZX_VM_CAN_MAP_READ新的 VMAR 可以包含可读映射。 如果父级没有ZX_VM_CAN_MAP_READ权限,则会出错。ZX_VM_CAN_MAP_WRITE新的 VMAR 可以包含可写映射。 如果父级没有ZX_VM_CAN_MAP_WRITE权限,则会出错。ZX_VM_CAN_MAP_EXECUTE新的 VMAR 可以包含可执行映射。 如果父级没有ZX_VM_CAN_MAP_EXECUTE权限,则会出错。
如果 options 未设置 ZX_VM_SPECIFIC 或 ZX_VM_OFFSET_IS_UPPER_LIMIT,则 offset 必须为 0。
此外,还可以添加以下 2 的幂对齐标志:
ZX_VM_ALIGN_1KB将 child_addr 对齐到至少 1K 字节的 2 的幂。ZX_VM_ALIGN_2KB将 child_addr 对齐到至少 2K 字节的 2 的幂。ZX_VM_ALIGN_4KB将 child_addr 对齐到至少 4K 字节的 2 的幂。ZX_VM_ALIGN_8KB将 child_addr 对齐到至少 8K 字节的 2 的幂。
并继续到
ZX_VM_ALIGN_4GB将 child_addr 对齐到至少 4G 字节的 2 的幂。
如果
parent_vmar 基地址 + offset 未与请求的
值对齐,则将 ZX_VM_ALIGN 标志与 ZX_VM_SPECIFIC 搭配使用会失败。
权限
如果 options & ZX_VM_CAN_MAP_READ,则 parent_vmar 必须为 ZX_OBJ_TYPE_VMAR 类型,并且具有 ZX_RIGHT_READ。
如果 options & ZX_VM_CAN_MAP_WRITE,则 parent_vmar 必须为 ZX_OBJ_TYPE_VMAR 类型,并且具有 ZX_RIGHT_WRITE。
如果 options & ZX_VM_CAN_MAP_EXECUTE,则 parent_vmar 必须为 ZX_OBJ_TYPE_VMAR 类型,并且具有 ZX_RIGHT_EXECUTE。
返回值
zx_vmar_allocate() 成功后会返回 ZX_OK、子区域的绝对基地址(通过 child_addr)以及新子区域的句柄(通过
child_vmar)。基地址将与页面对齐且不为零。
如果失败,则返回负错误值。
错误
ZX_ERR_BAD_HANDLE parent_vmar 不是有效的句柄。
ZX_ERR_WRONG_TYPE parent_vmar 不是 VMAR 句柄。
ZX_ERR_BAD_STATE parent_vmar 引用已销毁的 VMAR。
ZX_ERR_INVALID_ARGS 对于以下任一情况,返回
- child_vmar 或 child_addr 无效,
- 未提供
ZX_VM_SPECIFIC或ZX_VM_OFFSET_IS_UPPER_LIMIT时,offset 不为零。 ZX_VM_OFFSET_IS_UPPER_LIMIT与ZX_VM_SPECIFIC一起指定。- 由于超出区域边界,offset 和 size 描述了无法满足的分配。
- offset 或 size 未与页面对齐,或者 size 为 0。
ZX_ERR_NO_MEMORY 因内存不足而失败。
用户空间没有好的方法来处理此(不太可能发生的)错误。
在未来的版本中,此错误将不再发生。
ZX_ERR_NO_RESOURCES 如果在 VMAR 中找不到可用于分配区域的位置。
ZX_ERR_ACCESS_DENIED 权限不足,无法进行请求的分配。
备注
取消分配
VMAR 占用的地址空间将保持分配状态(在其
父级 VMAR 中),直到通过调用 zx_vmar_destroy() 销毁 VMAR 为止。
请注意,仅关闭 VMAR 的句柄不会取消分配 VMAR 占用的地址空间。
COMPACT 标志
内核会将此标志解释为减少分配中的蔓延的请求。 虽然这并不一定需要减少分配的地址的绝对熵,但分配之间可能会存在非常高的相关性。 如果开发者愿意让某些地址更相关,则可以进行这种权衡,以提高分配的局部性并减少所需的页表数量。