zxvmar_map

总结

添加内存映射。

声明

#include <zircon/syscalls.h>

zx_status_t zx_vmar_map(zx_handle_t handle,
                        zx_vm_option_t options,
                        size_t vmar_offset,
                        zx_handle_t vmo,
                        uint64_t vmo_offset,
                        size_t len,
                        zx_vaddr_t* mapped_addr);

说明

将指定的 VMO 映射到指定的虚拟内存地址区域。该映射会保留对底层虚拟内存对象的引用,这意味着关闭 VMO 句柄不会移除此函数添加的映射。

options 是以下值的位矢量:

  • ZX_VM_SPECIFIC 使用 vmar_offset 放置映射;如果 handle 没有 ZX_VM_CAN_MAP_SPECIFIC 权限,则无效。vmar_offset 是相对于给定 VMAR 基地址的偏移量。指定与其他 VMAR 或映射重叠的范围是错误的。
  • ZX_VM_SPECIFIC_OVERWRITEZX_VM_SPECIFIC 相同,但可以与其他映射重叠。与另一个 VMAR 部分重叠仍然会引发错误。如果该范围满足这些要求,它将以原子方式(相对于所有其他映射/取消映射/保护操作)替换 vmar_offsetlen 指定的范围内的现有映射。如果该范围与任何映射部分重叠,那么这些映射中超出该范围的部分将保持映射状态。
  • ZX_VM_OFFSET_IS_UPPER_LIMITvmar_offset 解读为上限,以限制内核对偏移量的选择;如果 handle 没有 ZX_VM_CAN_MAP_SPECIFIC 权限,则无效。生成的映射的 offset + len 将为 <= vmar_offset。如果使用 ZX_VM_SPECIFICZX_VM_SPECIFIC_OVERWRITE,则无法指定此选项。
  • ZX_VM_PERM_READvmo 映射为可读。如果 handle 没有 ZX_VM_CAN_MAP_READ 权限,handle 没有 ZX_RIGHT_READ 权限,或者 vmo 句柄没有 ZX_RIGHT_READ 权限,则会出错。
  • ZX_VM_PERM_WRITEvmo 映射为可写。如果 handle 没有 ZX_VM_CAN_MAP_WRITE 权限,handle 没有 ZX_RIGHT_WRITE 权限,vmo 句柄没有 ZX_RIGHT_WRITE 权限,或者 options 未指定 ZX_VM_PERM_READ,则会出错。
  • ZX_VM_PERM_EXECUTEvmo 映射为可执行文件。如果 handle 没有 ZX_VM_CAN_MAP_EXECUTE 权限,handle 句柄没有 ZX_RIGHT_EXECUTE 权限,vmo 句柄没有 ZX_RIGHT_EXECUTE 权限,或者 options 未指定 ZX_VM_PERM_READ,则会出错。
  • ZX_VM_MAP_RANGE 立即分页进入虚拟机的所有受支持区域的新映射。如果使用 ZX_VM_SPECIFIC_OVERWRITE,则无法指定此字段。
  • ZX_VM_ALLOW_FAULTS:如果创建的映射可能会生成故障,则为必需。具体而言,vmo 可调整大小、vmo 不可调整大小但映射超出 vmo 的末尾部分、vmo 可舍弃,或者 vmo 是从 zx_pager_create_vmo() 创建的,则必须提供此属性。
  • ZX_VM_PERM_READ_IF_XOM_UNSUPPORTED 如果系统不支持映射只执行页面,则将 vmo 映射为可读页面。如果系统可以映射只执行,系统会忽略此标志。

如果 options 未设置 ZX_VM_SPECIFICZX_VM_SPECIFIC_OVERWRITEZX_VM_OFFSET_IS_UPPER_LIMIT,则 vmar_offset 必须为 0。ZX_VM_OFFSET_IS_UPPER_LIMIT 用于限制选择范围,除此之外的行为类似于未设置 ZX_VM_SPECIFICZX_VM_SPECIFIC_OVERWRITE 的情况,因为内核会随机为映射分配偏移量(分配器由目标 VMAR 上设置的政策确定)。

len 必须是非零值且页面对齐。

此外,可以添加以下二次幂对齐标志之一:

  • 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 的幂。

如果 vmar 基础地址 + vmo_offset 与请求的值不一致,将 ZX_VM_ALIGN 标志与 ZX_VM_SPECIFIC 搭配使用会失败。

权限

handle 的类型必须为 ZX_OBJ_TYPE_VMAR

vmo 的类型必须为 ZX_OBJ_TYPE_VMO

返回值

zx_vmar_map() 会在成功时返回 ZX_OK 和映射的绝对基址(通过 mapped_addr)。基地址将与页面对齐,且为非零值。如果失败,则返回负数错误值。

错误

ZX_ERR_BAD_HANDLE handlevmo 不是有效的句柄。

ZX_ERR_WRONG_TYPE handlevmo 分别不是 VMAR 或 VMO 句柄。

ZX_ERR_BAD_STATE 句柄是指已销毁的 VMAR。

以下任意一项的 ZX_ERR_INVALID_ARGS: - mapped_addroptions 都无效。 - 如果未指定 ZX_VM_SPECIFICZX_VM_SPECIFIC_OVERWRITEZX_VM_OFFSET_IS_UPPER_LIMITvmar_offset 为非零值。 - 同时指定了 ZX_VM_SPECIFIC_OVERWRITEZX_VM_MAP_RANGE。 - ZX_VM_OFFSET_IS_UPPER_LIMITZX_VM_SPECIFICZX_VM_SPECIFIC_OVERWRITE 一起指定。 - vmar_offsetlen 描述了由于超出区域边界而导致不满足的分配。 - vmar_offsetvmo_offset 未进行页面对齐。 - len 为 0 或未页面对齐。

ZX_ERR_ALREADY_EXISTS ZX_VM_SPECIFIC 已在未指定 ZX_VM_SPECIFIC_OVERWRITE 的情况下指定,并且请求的范围与另一个映射重叠。

ZX_ERR_NO_RESOURCES:如果在 VMAR 中找不到时间点以创建映射。

ZX_ERR_ACCESS_DENIED权限不足,无法创建所请求的映射。

ZX_ERR_NOT_SUPPORTED:如果视频可调整大小、可舍弃或由分页器提供支持,但未设置 ZX_VM_ALLOW_FAULTS

ZX_ERR_BUFFER_TOO_SMALL:VMO 不可调整大小,且映射超出 VMO 的末尾,但 ZX_VM_ALLOW_FAULTS 未设置。

ZX_ERR_NO_MEMORY 由于内存不足而失败。 用户空间没有什么方法来处理此(不太可能)错误。在以后的 build 中,此错误不会再发生。

ZX_ERR_OUT_OF_RANGE vmo_offset + ROUNDUP(len, PAGE_SIZE)溢出。

备注

支持内存映射的 VMO 可调整为更小的大小。这可能会导致线程在读取 VMAR 区域或向 VMAR 区域写入数据时发生故障。为了避免此风险,从客户端接收 VMO 的服务应在映射 VMO 时使用 ZX_VM_REQUIRE_NON_RESIZABLE

另请参阅