Linux KVM 虚拟机调用¶
- X86
KVM 虚拟机调用具有 vmcall 或 vmmcall 指令的三字节序列。虚拟机监控程序可以用保证支持的指令替换它。
最多可以通过 rbx、rcx、rdx 和 rsi 分别传递四个参数。虚拟机调用号应放在 rax 中,返回值将放在 rax 中。除非特定虚拟机调用明确说明,否则不会破坏其他寄存器。
- S390
R2-R7 用于参数 1-6。此外,R1 用于虚拟机调用号。返回值写入 R2。
S390 使用诊断指令作为虚拟机调用 (0x500),并在 R1 中包含虚拟机调用号。
有关 KVM 支持的 S390 诊断调用的更多信息,请参阅 KVM 上的 s390 DIAGNOSE 调用。
- PowerPC
它使用 R3-R10 和 R11 中的虚拟机调用号。R4-R11 用作输出寄存器。返回值放在 R3 中。
KVM 虚拟机调用使用 4 字节操作码,这些操作码在设备树的 /hypervisor 节点内的“hypercall-instructions”属性中进行了修补。有关更多信息,请参阅 PPC KVM 半虚拟化接口
- MIPS
KVM 虚拟机调用使用代码为 0 的 HYPCALL 指令和 $2 (v0) 中的虚拟机调用号。最多可以将四个参数放入 $4-$7 (a0-a3) 中,返回值放在 $2 (v0) 中。
KVM 虚拟机调用文档¶
每个虚拟机调用的模板是:1. 虚拟机调用名称。2. 架构。3. 状态(已弃用、已过时、活动)。4. 目的
1. KVM_HC_VAPIC_POLL_IRQ¶
- 架构:
x86
- 状态:
活动
- 目的:
触发客户机退出,以便主机可以检查重新进入时是否有挂起的中断。
2. KVM_HC_MMU_OP¶
- 架构:
x86
- 状态:
已弃用。
- 目的:
支持 MMU 操作,例如写入 PTE、刷新 TLB、释放 PT。
3. KVM_HC_FEATURES¶
- 架构:
PPC
- 状态:
活动
- 目的:
向客户机公开虚拟机调用可用性。在 x86 平台上,cpuid 用于枚举哪些虚拟机调用可用。在 PPC 上,可以使用基于设备树的查找(这也是 EPAPR 规定的)或 KVM 特定的枚举机制(即此虚拟机调用)。
4. KVM_HC_PPC_MAP_MAGIC_PAGE¶
- 架构:
PPC
- 状态:
活动
- 目的:
为了实现虚拟机监控程序和客户机之间的通信,有一个共享页面,其中包含管理程序可见寄存器状态的部分。客户机可以映射此共享页面,以使用此虚拟机调用通过内存访问其管理程序寄存器。
5. KVM_HC_KICK_CPU¶
- 架构:
x86
- 状态:
活动
- 目的:
用于从 HLT 状态唤醒 vcpu 的虚拟机调用
- 用法示例:
一个半虚拟化客户机的 vcpu,在客户机内核模式下忙等待某个事件发生(例如:自旋锁变为可用)后,一旦忙等待超过阈值时间间隔,就可以执行 HLT 指令。执行 HLT 指令将导致虚拟机监控程序使 vcpu 进入睡眠状态,直到发生适当的事件。同一客户机的另一个 vcpu 可以通过发出 KVM_HC_KICK_CPU 虚拟机调用来唤醒睡眠的 vcpu,并指定要唤醒的 vcpu 的 APIC ID (a1)。虚拟机调用中使用了额外的参数 (a0) 以备将来使用。
6. KVM_HC_CLOCK_PAIRING¶
- 架构:
x86
- 状态:
活动
- 目的:
用于同步主机和客户机时钟的虚拟机调用。
用法
a0:主机复制“struct kvm_clock_offset”结构的客户机物理地址。
a1:clock_type,目前仅支持 KVM_CLOCK_PAIRING_WALLCLOCK (0)(对应于主机的 CLOCK_REALTIME 时钟)。
struct kvm_clock_pairing { __s64 sec; __s64 nsec; __u64 tsc; __u32 flags; __u32 pad[9]; };
- 其中
sec:clock_type 时钟的秒数。
nsec:clock_type 时钟的纳秒数。
tsc:用于计算 sec/nsec 对的客户机 TSC 值
flags:标志,目前未使用 (0)。
虚拟机调用使客户机可以计算主机和客户机之间的精确时间戳。客户机可以使用返回的 TSC 值来计算其时钟的 CLOCK_REALTIME,在同一时刻。
如果主机不使用 TSC 时钟源,或者时钟类型与 KVM_CLOCK_PAIRING_WALLCLOCK 不同,则返回 KVM_EOPNOTSUPP。
6. KVM_HC_SEND_IPI¶
- 架构:
x86
- 状态:
活动
- 目的:
向多个 vCPU 发送 IPI。
a0:目标 APIC ID 位图的较低部分
a1:目标 APIC ID 位图的较高部分
a2:位图中最低的 APIC ID
a3:APIC ICR
虚拟机调用允许客户机发送多播 IPI,在 64 位模式下每个虚拟机调用最多 128 个目标,在 32 位模式下每个虚拟机调用最多 64 个 vCPU。目标由前两个参数(a0 和 a1)中包含的位图表示。a0 的第 0 位对应于第三个参数 (a2) 中的 APIC ID,第 1 位对应于 APIC ID a2+1,依此类推。
返回成功传递 IPI 的 CPU 数量。
7. KVM_HC_SCHED_YIELD¶
- 架构:
x86
- 状态:
活动
- 目的:
如果 IPI 目标 vCPU 被抢占,则用于让步的虚拟机调用
a0:目标 APIC ID
- 用法示例:
当向 vCPU 发送 call-function IPI-many 时,如果任何 IPI 目标 vCPU 被抢占,则让步。
8. KVM_HC_MAP_GPA_RANGE¶
- 架构:
x86
- 状态:
活动
- 目的:
请求 KVM 使用指定的属性映射 GPA 范围。
a0:起始页的客户机物理地址 a1:页面数(4kb)(必须在 GPA 空间中连续) a2:属性
- 其中“属性”
位 3:0 - 首选页面大小编码 0 = 4kb,1 = 2mb,2 = 1gb,等等...
位 4 - 明文 = 0,加密 = 1
位 63:5 - 保留(必须为零)
实现说明:此虚拟机调用通过 KVM_CAP_EXIT_HYPERCALL 功能在用户空间中实现。用户空间必须先启用该功能,然后在客户机 CPUID 中通告 KVM_FEATURE_HC_MAP_GPA_RANGE。此外,如果客户机支持 KVM_FEATURE_MIGRATION_CONTROL,则用户空间还必须设置 MSR 过滤器以处理对 MSR_KVM_MIGRATION_CONTROL 的写入。