硬件虚拟化让一个 CPU 上运行多个 OS → 但每次 VM-exit 都有代价。
一、先看图
flowchart TD
GUEST[Guest OS] -->|敏感指令| VMEXIT[VM-exit<br/>陷入 VMM]
VMEXIT --> VMM[VMM / Hypervisor<br/>处理]
VMM --> VMENTRY[VM-entry<br/>返回 Guest]
VMENTRY --> GUEST
GUEST2[Guest 内存访问] --> EPT[EPT/NPT<br/>二级页表翻译]
EPT --> PHYS[物理内存]
classDef guest fill:#388bfd22,stroke:#388bfd,color:#adbac7;
classDef vmm fill:#f0883e22,stroke:#f0883e,color:#adbac7;
class GUEST,GUEST2,VMENTRY guest
class VMEXIT,VMM vmm
class EPT,PHYS guest
二、硬件支持
2.1 Intel VT-x(VMX)
VMXON → 启用 VMX 模式
VMLAUNCH/VMRESUME → 进入 Guest(VM-entry)
Guest 执行敏感指令 → VM-exit → 回到 VMM
VMCS(Virtual Machine Control Structure)控制 VM-exit 条件。
2.2 AMD-V(SVM)
VMRUN → 进入 Guest
#VMEXIT → 回到 Host
VMCB(Virtual Machine Control Block)= AMD 版 VMCS。
三、VM-exit 原因
| 原因 | 说明 |
|---|---|
| I/O 指令 | in/out |
| MSR 访问 | rdmsr/wrmsr |
| 中断 | 外部中断 |
| CPUID | CPU 特性查询 |
| EPT violation | 内存映射缺失 |
| HLT | CPU 空闲 |
四、EPT / NPT
4.1 问题
Guest 页表:GVA → GPA(Guest Physical Address)
需要再翻译:GPA → HPA(Host Physical Address)
4.2 二级页表
GVA → Guest 页表 → GPA → EPT/NPT → HPA
硬件自动完成两级翻译 → 不需要 VMM 介入 → 大幅减少 VM-exit。
4.3 代价
TLB miss 时需要遍历两级页表 → 最多 24 次内存访问(4 级 × 4 级 + TLB 填充)。
五、APICv 与 Posted Interrupts
传统:Guest 的中断 → VM-exit → VMM 注入。
APICv:硬件直接将中断送到 Guest → 不需要 VM-exit。
Posted Interrupt = 硬件把中断写入 Guest 的虚拟 APIC → 直接唤醒 vCPU
六、vCPU 调度
vCPU 是宿主的线程 → 由宿主调度器调度。
问题:
- vCPU 被抢占时持有 Guest spinlock → 其他 vCPU 自旋等待(Lock Holder Preemption)
- 解决:PV spinlock → Guest 检测到 vCPU 被抢占 → 让出
七、Nested Virtualization
L0(硬件)→ L1(Host VMM)→ L2(Guest VMM)→ L3(Guest)
L2 的 VM-exit → 可能需要 L1 处理 → 性能开销大。
八、PV(Paravirtualization)
Guest 知道自己在虚拟化环境中 → 使用优化的接口:
| PV 机制 | 用途 |
|---|---|
| PV clock | 时钟同步 |
| PV spinlock | 避免 lock holder preemption |
| PV TLB flush | 批量 TLB flush |
| virtio | I/O 虚拟化 |
九、观察
# 检查硬件虚拟化支持
grep -cE 'vmx|svm' /proc/cpuinfo
# KVM 模块
lsmod | grep kvm
# VM-exit 统计(在 Host 上)
perf kvm stat live
# Guest 内
dmesg | grep -i "hypervisor\|kvm\|vmware"十、小结
- VMX/SVM 提供硬件虚拟化 → VM-exit/VM-entry 切换
- EPT/NPT 二级页表减少内存访问的 VM-exit
- APICv + posted interrupts 减少中断的 VM-exit
- vCPU 调度要注意 lock holder preemption
- PV 接口进一步优化性能
参考文献
- Intel SDM Volume 3, Chapter 23-28(VMX)
- AMD APM Volume 2, Chapter 15(SVM)
arch/x86/kvm/Documentation/virt/kvm/
工具
perf kvm/proc/cpuinfovirsh
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【操作系统百科】内存回收
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。
【操作系统百科】交换
swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。
【操作系统百科】Slab/SLUB 分配器
buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。
【操作系统百科】用户态分配器
glibc malloc、tcmalloc、jemalloc、mimalloc 各有哲学。本文讲 arena、thread cache、size class、madvise 返还策略、碎片与 RSS 膨胀、如何根据负载选分配器。