1. 课程导入
在云计算与服务器虚拟化场景中,内存是最容易被低估、却最直接影响虚拟机性能与密度的资源。CPU 虚拟化解决的是“指令在哪里执行”,而内存虚拟化解决的是“指令访问的地址最终落到哪一块物理内存”。KVM 作为 Linux 内核原生的虚拟化模块,其内存虚拟化能力建立在 x86 硬件辅助虚拟化之上,核心机制就是 Stage-2 映射(在 Intel 平台称为 EPT,在 AMD 平台称为 NPT)。理解 Stage-2,是理解 KVM 虚拟机内存性能、内存超分、热迁移、嵌套虚拟化等一系列高级主题的起点。
一、学习目标:从“会用”到“看得懂、调得动”
本课程不是简单地罗列 KVM 命令,而是希望建立一条从硬件到内核、从内核到 QEMU、从 QEMU 到虚拟机内部的可追踪链路。完成学习后,你应当能够达到以下目标:
- 能说清 GVA、GPA、HVA、HPA 四类地址之间的转换关系,以及每一级由谁负责翻译。
- 能解释 Stage-1(客户机页表)与 Stage-2(EPT/NPT)的分工,理解为什么需要两级翻译。
- 能读懂
/sys/kernel/debug/kvm/下的关键统计,判断 EPT 缺页、大页使用与 MMU 缓存命中情况。 - 能结合场景选择内存分配方式:匿名内存、HugePage、THP、NUMA 绑定与内存超分策略。
- 能定位常见内存虚拟化问题:性能抖动、内存泄漏、迁移失败、嵌套虚拟化异常。
二、Stage-2 映射核心概念:两级地址翻译
在没有虚拟化时,进程访问内存只需一次页表翻译:虚拟地址 VA → 物理地址 PA。引入虚拟机后,情况变成两级:虚拟机内部看到的“物理地址”其实并不是真正的物理地址,而是客户机物理地址 GPA。CPU 在执行客户机代码时,需要先把客户机虚拟地址 GVA 翻译成 GPA(Stage-1,由客户机页表完成),再把 GPA 翻译成宿主机物理地址 HPA(Stage-2,由 EPT/NPT 完成)。
硬件辅助虚拟化的价值在于:这两级翻译由 MMU 在一次遍历中协同完成,不需要为每次访问陷入 VMM。Stage-2 页表由 KVM 维护,QEMU 通过 KVM_SET_USER_MEMORY_REGION 等 ioctl 把虚拟机的内存槽(memory slot)注册给 KVM,KVM 再据此建立 GPA → HVA → HPA 的映射。因此,Stage-2 既是隔离边界,也是性能关键路径。
三、整体知识框架:从地址翻译到性能调优
本课程的知识框架可以分成四层,层层递进:
| 层次 | 核心问题 | 关键对象 | 典型工具/接口 |
|---|---|---|---|
| 地址翻译层 | GVA 如何最终落到 HPA | Stage-1、Stage-2、TLB、MMU | EPT/NPT、CR3、VPID |
| 内存管理接口层 | QEMU 如何把内存交给 KVM | memory slot、HVA、RAMBlock | KVM_SET_USER_MEMORY_REGION |
| 性能优化层 | 如何降低翻译开销与缺页开销 | 大页、THP、HugePage、TLB 命中 | KVM 统计、perf、tracepoint |
| 高级场景层 | 超分、热迁移、嵌套虚拟化如何工作 | 脏页跟踪、影子页表、L2 EPT | dirty log、migration、nested |
可以看到,Stage-2 并不是孤立的一层,它向上承接 QEMU 的内存槽注册,向下依赖硬件 EPT/NPT 能力,同时又被大页、TLB、脏页跟踪等机制影响。学习时如果只记住“EPT 是硬件加速的页表”,很容易在遇到性能问题时无从下手。
四、典型场景:一次客户机内存访问发生了什么
假设虚拟机内一个应用程序读取变量 x,地址为 GVA。CPU 首先用客户机 CR3 找到 Stage-1 页表,把 GVA 翻译为 GPA;随后 MMU 使用 EPTP(EPT 指针)找到 Stage-2 页表,把 GPA 翻译为 HPA;最后访问 HPA 对应的物理内存。如果 Stage-2 页表中该 GPA 尚未建立映射,就会触发 EPT Violation,KVM 捕获后根据 memory slot 找到对应的 HVA,再建立 GPA → HPA 映射,并重新执行指令。
# 查看 KVM 全局统计,观察 EPT 缺页与 MMU 缓存情况
cat /sys/kernel/debug/kvm/* 2>/dev/null | head -n 40
# 典型关注字段
# ept_violation : Stage-2 缺页次数
# mmu_cache_miss : MMU 缓存未命中
# mmu_shadow_zapped : 影子页表回收次数
# hugepages : 大页使用情况
ept_violation 持续偏高时,通常意味着 Stage-2 映射建立不充分或内存访问模式导致频繁缺页。此时应优先检查是否启用大页、是否发生内存超分、以及客户机是否频繁申请/释放内存。
五、常见误区与复盘
- 误区一:把 GPA 当成真实物理地址。 GPA 只是客户机视角的“物理地址”,真正落到 DRAM 的是 HPA,中间必须经过 Stage-2。
- 误区二:认为 EPT 一定比影子页表快。 EPT 减少了 VM Exit,但两级页表遍历本身有开销;如果缺页频繁,性能仍可能下降。
- 误区三:忽略 memory slot 的对齐与合并。 不合理的 slot 划分会增加 KVM 查找开销,甚至影响热迁移的脏页跟踪效率。
- 误区四:只调 QEMU 参数,不看 KVM 统计。 性能问题往往需要结合
/sys/kernel/debug/kvm/与perf kvm一起判断。
接下来的章节将沿着“地址翻译 → Stage-2 建立 → 性能优化 → 高级场景”的路径逐步展开。本章只需要建立一张全局地图:GVA、GPA、HVA、HPA 四类地址,Stage-1 与 Stage-2 两级翻译,以及 KVM、QEMU、硬件 MMU 三者的分工。把这张地图记牢,后续每一章都会在这张地图上增加新的细节。