1. 内存虚拟化基础概念
内存虚拟化是现代虚拟化技术的核心组成部分,它解决了虚拟机如何安全高效地访问物理内存的问题。在传统非虚拟化环境中,CPU的内存管理单元(MMU)通过页表直接将虚拟地址(VA)转换为物理地址(PA)。但在虚拟化环境中,这种简单的两级转换无法满足需求,因为虚拟机操作系统(Guest OS)认为自己独占物理内存,而实际上这些"物理内存"还需要被虚拟化管理程序(VMM)再次映射到真实的物理内存。
1.1 地址空间转换层次
在虚拟化环境中,地址转换从传统的两级扩展为三级:
code复制Guest Virtual Address (GVA) → Guest Physical Address (GPA) → Host Physical Address (HPA)
这种三级转换带来了几个关键挑战:
- 转换效率:每次内存访问需要额外的地址转换步骤
- 隔离性:必须确保不同虚拟机的地址空间完全隔离
- 透明性:Guest OS不应感知到这种额外的转换层次
1.2 关键术语解析
- GVA(Guest Virtual Address):Guest OS中的虚拟地址,与普通进程的虚拟地址概念相同
- GPA(Guest Physical Address):Guest OS认为的"物理地址",实际上是VMM维护的中间层地址
- HPA(Host Physical Address):真实的物理内存地址,由VMM最终管理
- HVA(Host Virtual Address):VMM进程地址空间中的虚拟地址,用于管理Guest内存
提示:理解这些地址空间的层次关系是掌握内存虚拟化的基础。可以类比为"虚拟地址是邮寄地址中的房间号,GPA是办公楼地址,HPA则是实际的地理坐标"。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 传统影子页表技术
在硬件辅助虚拟化技术出现前,影子页表(Shadow Page Table)是解决内存虚拟化的主要方案。其核心思想是由VMM为每个Guest维护一套"影子"页表,直接建立GVA到HPA的映射,绕过GPA这一中间层。
2.1 影子页表工作原理
影子页表的工作流程可以分解为以下几个步骤:
-
初始化阶段:
- VMM创建初始的影子页表,内容与Guest页表一致但地址转换为HPA
- 将Guest的CR3寄存器指向的影子页表根设置为只读
-
运行时阶段:
- Guest尝试修改页表时触发页错误(Page Fault)
- VMM捕获该错误,解析Guest的页表修改意图
- VMM同步更新对应的影子页表项
- 恢复Guest执行
c复制// 简化的影子页表同步逻辑
void sync_shadow_page(struct kvm_vcpu *vcpu, gpa_t guest_pt_gpa) {
// 1. 将Guest页表GPA转换为HPA
hpa_t guest_pt_hpa = gpa_to_hpa(vcpu->kvm, guest_pt_gpa);
// 2. 找到对应的影子页表
struct kvm_mmu_page *sp = find_shadow_page(vcpu, guest_pt_gpa);
// 3. 逐项同步
for (int i = 0; i < PT_ENTRIES; i++) {
u64 gpte = read_guest_
