Skip to the content.

KVM hypercall

这些 hypercall 有实际调用者,但不是每个都有现役调用者,也不是所有架构都支持。

各 hypercall 的调用情况

include/uapi/linux/kvm_para.h

Hypercall 哪些 guest / 场景会调用 当前状态及调用位置
KVM_HC_VAPIC_POLL_IRQ Windows XP 等旧 guest 的虚拟 APIC 加速代码;更新 TPR 后,触发 VM exit,让 host 检查待处理中断 Linux guest 内核未找到调用;QEMU 的 kvmvapic.S 有明确调用
KVM_HC_MMU_OP 早期 x86 Linux 的半虚拟化 MMU:写 PTE、刷新 TLB、释放页表 已废弃;当前无调用及 host 实现,编号仍保留
KVM_HC_FEATURES PPC Linux guest 查询 KVM 半虚拟化能力 arch/powerpc/include/asm/kvm_para.h,第 20 行 kvm_arch_para_features();x86 使用 CPUID 查询
KVM_HC_PPC_MAP_MAGIC_PAGE PPC Linux guest 初始化时映射共享页,通过内存访问部分特权寄存器状态 arch/powerpc/kernel/kvm.c,第 403 行 kvm_map_magic_page()
KVM_HC_KICK_CPU x86 Linux 启用 PV spinlock 时,唤醒因等锁而 halt 的 vCPU arch/x86/kernel/kvm.c,第 1067 行 kvm_kick_cpu()
KVM_HC_MIPS_GET_CLOCK_FREQ    
KVM_HC_MIPS_EXIT_VM    
KVM_HC_MIPS_CONSOLE_OUTPUT    
KVM_HC_CLOCK_PAIRING x86 Linux 的 ptp_kvm 驱动初始化、读取时钟或交叉时间戳,获取 host 时间与 guest TSC 的配对 drivers/ptp/ptp_kvm_x86.c,第 53、81、114 行
KVM_HC_SEND_IPI x86 Linux 启用 PV IPI 后,向一组 vCPU 发送 IPI arch/x86/kernel/kvm.c,__send_ipi_mask() 第 549、560 行
KVM_HC_SCHED_YIELD x86 Linux 发送 call-function IPI 后,发现目标 vCPU 被 host 抢占,请求 host 尝试让目标运行 arch/x86/kernel/kvm.c,第 645 行 kvm_smp_send_call_func_ipi()

存在调用代码,不代表每台 VM 都会调用

KICK_CPU、SEND_IPI、SCHED_YIELD 受 KVM feature、SMP 和 guest 配置等条件控制;CLOCK_PAIRING 要走到 ptp_kvm 驱动路径。

相关条件见 arch/x86/kernel/kvm.c 的 pv_ipi_supported()、pv_sched_yield_supported() 和 kvm_spinlock_init()。

VAPIC_POLL_IRQ 的空操作有实际用途

host 分支虽然只是 ret = 0,但触发 VM exit 本身就是目的:使 host 在重新进入 guest 前检查待处理中断,不能据此判断它没用。

见 arch/x86/kvm/x86.c 第 10431 行。QEMU 的 kvmvapic.S 在 mp_set_tpr_poll_irq 和 up_set_tpr_poll_irq 中把编号 1 放入 EAX,再执行 hypercall。这些代码运行在 guest 中。

实验

x86 host 已有 kvm:kvm_hypercall tracepoint,

配合 ./test.c 运行,结果为:

129654.250 CPU 0/KVM/1772113 kvm:kvm_hypercall()
131557.154 CPU 0/KVM/1772113 kvm:kvm_hypercall()
132227.864 CPU 0/KVM/1772113 kvm:kvm_hypercall()
132900.642 CPU 0/KVM/1772113 kvm:kvm_hypercall()

KVM_HC_SEND_IPI 是可以普遍观察到的日志

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。