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 权限。生成的映射 将具有偏移值 + 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 立即转到所有支持的新映射 VMO 的各区域。如果出现以下情况,则无法指定此项: ZX_VM_SPECIFIC_OVERWRITE
  • ZX_VM_ALLOW_FAULTS 必需(如果可以创建) 映射以生成故障。特别是,如果 vmo 可调整大小,则必须使用此属性, 如果 vmo 不可调整大小,但映射超出了 vmo 的末尾,则 vmo 可舍弃,或者 vmo 是通过 zx_pager_create_vmo() 创建的。
  • ZX_VM_PERM_READ_IF_XOM_UNSUPPORTEDvmo 映射到可读状态(如果系统执行该操作) 不支持映射只执行页面。如果系统可以映射只执行 则忽略此标志。
  • ZX_VM_REQUIRE_NON_RESIZABLE 如果 vmo 可调整大小,则失败。

如果 options 不包含 ZX_VM_SPECIFIC,则 vmar_offset 必须为 0, 已设置 ZX_VM_SPECIFIC_OVERWRITEZX_VM_OFFSET_IS_UPPER_LIMITZX_VM_OFFSET_IS_UPPER_LIMIT 用于限制选择范围,以及 在其他情况下,行为与 ZX_VM_SPECIFIC 和 已设置 ZX_VM_SPECIFIC_OVERWRITE,并为映射分配了一个偏移量 (分配器由内核上设置的政策决定) 目标 VMAR)。

len 必须为非零并页面对齐。

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

  • ZX_VM_ALIGN_1KBchild_addr 与至少 1K 字节的 2 次方对齐。
  • ZX_VM_ALIGN_2KBchild_addr 与至少 2K 字节的 2 幂对齐。
  • ZX_VM_ALIGN_4KBchild_addr 与至少 4K 字节的 2 次方对齐。
  • ZX_VM_ALIGN_8KBchild_addr 与至少 8K 字节的 2 幂对齐。 并持续到
  • ZX_VM_ALIGN_4GBchild_addr 与至少 4G 字节的 2 次方对齐。

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

权限

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 无效。 - vmar_offsetZX_VM_SPECIFICZX_VM_SPECIFIC_OVERWRITE 或 已指定 ZX_VM_OFFSET_IS_UPPER_LIMIT。 - 同时指定了 ZX_VM_SPECIFIC_OVERWRITEZX_VM_MAP_RANGE。 - ZX_VM_OFFSET_IS_UPPER_LIMITZX_VM_SPECIFIC 中的任一项一起指定 或 ZX_VM_SPECIFIC_OVERWRITE。 - vmar_offsetlen 表示因超出区域边界而不能满足的分配情况。 - vmar_offsetvmo_offset 未对齐页面。 - len 为 0 或未页面对齐。

已指定 ZX_ERR_ALREADY_EXISTSZX_VM_SPECIFIC,但未指定 ZX_VM_SPECIFIC_OVERWRITE,并且请求的范围与另一个映射重叠。

ZX_ERR_NO_RESOURCES 如果在 VMAR 中找不到位置以创建映射。

ZX_ERR_ACCESS_DENIED权限不足,无法完成请求的映射。

ZX_ERR_NOT_SUPPORTED:vmo 可调整大小、可舍弃或由分页器支持,但 未设置 ZX_VM_ALLOW_FAULTS

ZX_ERR_NOT_SUPPORTED:如果 vmo 可调整大小且已设置 ZX_VM_REQUIRE_NON_RESIZABLE

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

ZX_ERR_NO_MEMORY 因内存不足而失败。 用户空间没有好办法处理这种(不太可能)错误。 在将来的版本中,此错误不会再发生。

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

备注

可以将支持内存映射的 VMO 的大小调整为更小的大小。这可能会导致 线程正在对错误的 VMAR 区域执行读取或写入操作。为了避免这种危险, 从客户端接收 VMO 的客户端在映射时应使用 ZX_VM_REQUIRE_NON_RESIZABLE VMO。

另请参阅