数据类型

保留值

此规范将某些字段记录为“保留”。 这些字段在虚拟机监控程序体系结构的未来版本中可能具有特定的含义。 为了最大程度地实现向前兼容性,虚拟机监控程序接口的客户端应遵循本文档中提供的指南。 一般情况下,提供两种形式的指导。 保留值 (关系图中记录为 RsvdP,在代码段) 中记录为 ReservedP – 为了最大程度地实现向前兼容性,客户端应保留此字段中的值。 这通常是通过读取当前值、修改非保留字段的值以及写回值来完成的。 零值 (关系图中记录为 RsvdZ,在代码段) 中记录为 ReservedZ – 为实现最大向前兼容性,客户端应将此字段中的值归零。

只读结构中的保留字段在关系图中仅记录为 Rsvd,在代码段中仅记录为保留字段。 为获得最大的向前兼容性,应忽略这些字段中的值。 客户端不应假定这些值始终为零。

简单标量类型

虚拟机监控程序数据类型由简单的标量类型 UINT8、UINT16、UINT32、UINT64 和 UINT128 构建。 其中每个都表示具有指定位计数的简单无符号整数标量。 还定义了多个相应的带符号整数标量:INT8、INT16、INT32 和 INT64。 虚拟机监控程序既不使用浮点指令,也不使用浮点类型。

Hypercall 状态代码

每个 hypercall 都会返回类型为 HV_STATUS 的 16 位状态代码。

typedef UINT16 HV_STATUS;

内存地址空间类型

虚拟机监控程序体系结构定义了三个独立的地址空间:

  • 系统物理地址 (SPA) 定义 CPU 所看到的基础硬件的物理地址空间。 整个计算机只有一个系统物理地址空间。
  • 来宾物理地址 (GPO) 定义来宾的物理内存视图。 GPA 可以映射到基础 SPA。 每个分区有一个来宾物理地址空间。
  • 启用地址转换并提供有效的来宾页表时,来宾虚拟地址 (GVA) 在来宾中使用。

这三个地址空间的大小最大为 264 个字节。 因此定义了以下类型:

typedef UINT64 HV_SPA;
typedef UINT64 HV_GPA;
typedef UINT64 HV_GVA;

许多虚拟机监控程序接口作用于内存页,而不是单个字节。 最小页面大小取决于体系结构。 对于 x64,它定义为 4K。

#define X64_PAGE_SIZE 0x1000

#define HV_X64_MAX_PAGE_NUMBER (MAXUINT64/X64_PAGE_SIZE)
#define HV_PAGE_SIZE X64_PAGE_SIZE
#define HV_LARGE_PAGE_SIZE X64_LARGE_PAGE_SIZE
#define HV_PAGE_MASK (HV_PAGE_SIZE - 1)

typedef UINT64 HV_SPA_PAGE_NUMBER;
typedef UINT64 HV_GPA_PAGE_NUMBER;
typedef UINT64 HV_GVA_PAGE_NUMBER;
typedef UINT32 HV_SPA_PAGE_OFFSET
typedef HV_GPA_PAGE_NUMBER *PHV_GPA_PAGE_NUMBER;

若要将 转换为 HV_SPAHV_SPA_PAGE_NUMBER,只需除以 HV_PAGE_SIZE

结构、枚举和位字段

本规范后面定义的许多数据结构和常量值都是根据 C 样式枚举和结构定义的。 C 语言故意避免定义某些实现详细信息。 但是,本文档假定以下内容:

  • 所有使用“enum”关键字声明的枚举都定义了 32 位有符号整数值。
  • 填充所有结构时,字段自然对齐 (即,8 字节字段与 8 字节的偏移量对齐,依此类) 。
  • 所有位字段都从低位打包到高位位,无需填充。

字节排序方式

虚拟机监控程序接口设计为与 endian 无关 (也就是说,应该可以将虚拟机监控程序移植到 big-endian 或 little-endian 系统) ,但本规范后面定义的某些数据结构采用 little-endian 布局。 如果尝试使用大端端口,则需要修改此类数据结构。

指针命名约定

文档对指针类型使用命名约定。 具体而言,在定义的类型前面追加的“P”指示指向该类型的指针。 在定义的类型前面追加的“PC”指示指向该类型的常量值的指针。