vmar_allocate —— 分配新的子VMAR区域
#include <zircon/syscalls.h>
zx_status_t zx_vmar_allocate(zx_handle_t parent_vmar, zx_vm_option_t options,
uint64_t offset, uint64_t size,
zx_handle_t* child_vmar, zx_vaddr_t* child_addr)
在parent_vmar指定的VMAR中创建新的子VMAR。
options是一个位向量,包含以下选项中的一个或多个:
- ZX_VM_COMPACT:提示内核应该保持新创建的子区域内的分配和映射关系。有关讨论,请参阅下面的注释部分。
- ZX_VM_SPECIFIC:使用offset指定映射,但如果VMAR没有ZX_VM_CAN_MAP_SPECIFIC权限,则无效。 offset是相对于父区域基地址的偏移量。 指定的地址范围与另一个VMAR或映射有重叠部分会导致错误。
- ZX_VM_CAN_MAP_SPECIFIC:新VMAR可以使用ZX_VM_SPECIFIC创建子区域/映射。 如果父级VMAR没有ZX_VM_CAN_MAP_SPECIFIC权限,不会导致错误。
- ZX_VM_CAN_MAP_READ:新VMAR可包含可读区域的映射。 但如果父级VMAR没有ZX_VM_CAN_MAP_READ权限,则会导致错误。
- ZX_VM_CAN_MAP_WRITE:新VMAR可包含可写区域的映射。 但如果父级VMAR没有ZX_VM_CAN_MAP_WRITE权限,则会导致错误。
- ZX_VM_CAN_MAP_EXECUTE:新VMAR可包含可执行区域的映射。 但如果父级VMAR没有ZX_VM_CAN_MAP_EXECUTE权限,则会导致错误。
如果options没有设置ZX_VM_SPECIFIC选项,则offset必须为0。
TODO(ZX-2399)
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无效;offset在未指定ZX_VM_SPECIFIC选项时为非零;offset和size指定了由于超出区域范围而导致的不可满足的分配;offset或size不是页面对齐的;或者size是0。
ZX_ERR_NO_MEMORY:由于内存不足导致的失败。 而用户空间无法处理这个(不太可能发生的)错误。 在将来的构建版本中,将不再出现此错误。
ZX_ERR_ACCESS_DENIED:没有足够的权限来执行分配请求。
内核将此标志解释为试图减少分配产生的蔓延的请求。 虽然这不需要降低分配地址的绝对熵,但分配之间可能因此存在非常高的相关性。 如果开发人员愿意让某些地址更加相关,那么可以通过这种权衡来增加分配的局部性并减少必要的页表数量。