01 kvm_main 核心机制与实现详解

01 kvm_main 核心机制与实现详解

1. 文件角色

virt/kvm/kvm_main.c(约 6000+ 行)是 所有架构共享的 KVM 核心:字符设备、VM/VCPU 生命周期、Guest 内存槽、MMU notifier、调试fs、停机轮询(halt poll)、与 kvm_arch_* 协作的枢纽。

文件头注释仍提及 Intel VT-x 历史;现代 ARM64 同样依赖此文件的 通用 ioctl 与资源管理

2. 模块入口与 /dev/kvm

1
2
3
4
5
static struct miscdevice kvm_dev = {
KVM_MINOR,
"kvm",
&kvm_chardev_ops,
};

kvm_dev_ioctl 处理:

ioctl 行为
KVM_GET_API_VERSION 返回 KVM_API_VERSION
KVM_CREATE_VM kvm_dev_ioctl_create_vmanon_inode + kvm_vm_fops
KVM_CHECK_EXTENSION 能力探测(含 arch 扩展)
KVM_GET_VCPU_MMAP_SIZE kvm_run 映射大小(+ 可选 coalesced mmio 页)
其它 kvm_arch_dev_ioctl(架构特定)

KVM_CREATE_VM 流程:

  1. get_unused_fd_flags
  2. kvm_create_vm(type, fdname) → 分配 struct kvm,调用 kvm_arch_init_vm
  3. anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR)
  4. fd_install 返回 VM fd。

3. 三级 file_operations

CREATE_VMCREATE_VCPU/dev/kvm kvm_chardev_opsVM fd kvm_vm_fopsVCPU fd kvm_vcpu_fops
  • VM ioctl:内存区域、irq 路由、寄存器级设备、dirty log 等;
  • VCPU ioctlKVM_RUN、寄存器 get/set、中断、调试;
  • KVM device ioctlkvm_device_ioctl):API 2.0 设备模型(如 VFIO 设备、架构 vGIC 设备在 arch 注册)。

4. VCPU 运行与请求机制

  • vcpu_load / vcpu_put:绑定 VCPU 到当前 CPU,准备进入 guest;
  • kvm_make_vcpu_request:设置 vcpu->requests 位(TLB flush、kick 等);
  • kvm_kick_many_cpus:IPI 唤醒执行 KVM_RUN 的线程;
  • halt_poll_ns:guest halt 时自旋轮询再阻塞,降低唤醒延迟(模块参数可调)。

ARM64:kvm_arch_vcpu_should_kickarm.c 根据 IN_GUEST_MODE 判断。

5. Guest 内存(memslots)

用户态通过 KVM_SET_USER_MEMORY_REGION 注册 GPA→HVA 区间:

  • 内核维护 address spacememory slots
  • mmu_notifier 挂钩:host 页面迁移/释放时 kvm_mmu_notifier_invalidate_range 使 guest 映射失效;
  • huge pageread-only memslotprivate memslot 等由通用层 + arch 支持。

kvm_pfn_to_refcounted_pagekvm_is_zone_device_page 处理特殊内存类型。

6. TLB 与影子页表

  • kvm_flush_remote_tlbs:请求所有 VCPU 刷新 guest TLB(调用 kvm_arch_flush_remote_tlbs);
  • kvm_flush_shadow_all:MMU shadow 相关(x86 为主,ARM 使用 Stage-2 由 mmu.c 实现)。

7. mmu_notifier

当 host 进程内存被 pin/unpin、migrate、munmap 时:

1
2
3
4
static void kvm_mmu_notifier_invalidate_range(struct mmu_notifier *mn, ...)
{
kvm_arch_mmu_notifier_invalidate_range(kvm, ...);
}

保证 QEMU 用户态内存guest 物理地址 一致性,是 KVM 正确性的基石。

8. 调试与统计

  • kvm_debugfs_dir:debugfs 入口(/sys/kernel/debug/kvm/);
  • binary_stats.c:向用户态导出二进制统计(配合 tools/perf 等生态);
  • tracepointstrace/events/kvm.hCREATE_TRACE_POINTSkvm_main.c

9. 弱符号扩展点

架构未实现时使用空 weak 函数,例如:

1
__weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, ...) { }

ARM64 在 mmu.c 等提供强符号覆盖。

10. 与 RK3588 的关系

  • RK3588 启用 KVM 时,所有 VM 创建/内存注册 均经 kvm_main.c
  • 异常退出、系统寄存器、VGIC 不在此文件;
  • 调优 halt poll 可影响虚拟 Android/VM 的 idle 延迟与 host CPU 占用。

11. 小结

kvm_main.c = KVM 资源管理与 ioctl 中枢;读 ARM KVM 须以此为基础,再进入 05-ARM64边界arm.c/handle_exit.c

文章互动

阅读 --

留言

0 条留言

正在加载留言…