trace_kvm_mmu_delay_free_pages(sp);call_rcu(&sp->rcu, free_pages_rcu); return; } @@ -2938,6 +2941,8 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct)if (direct) addr = 0;trace_handle_mmio_page_fault(addr, gfn, access);...
malloc 1M内存的时候并没有真正拿到物理内存,只是将分配的连续VMA映射到一片清零的物理地址并标注为readonly,只有当有人去写这块VMA的时候,MMU执行地址转换检查权限发现是只读,会被MMU拦截而触发page fault,但是内核检查到当前的地址权限是R+W,发现是malloc导致的page fault,然后分配物理内存页,改写权限,此刻真正拿到...
在每个虚拟机对应的 struct kvm_arch 结构中有一个 hash 表,mmu_page_hash[], 用于按 hash 方式组织虚拟机全部的 Shadow 页表页。 每次发生 CR3 改变或 Shadow 页表的“Page Fault”行为时,KVM 以 gfn 为参数,通过查找 hash 表,可确定对应的 Shadow 页表页是否在缓存中存在。 7. 对于那些采用非分页模式的...
在每个虚拟机对应的 struct kvm_arch 结构中有一个 hash 表,mmu_page_hash[], 用于按 hash 方式组织虚拟机全部的 Shadow 页表页。 每次发生 CR3 改变或 Shadow 页表的“Page Fault”行为时,KVM 以 gfn 为参数,通过查找 hash 表,可确定对应的 Shadow 页表页是否在缓存中存在。 7. 对于那些采用非分页模式的...
{ r = vcpu->arch.mmu.page_fault(vcpu, cr2, lower_32_bits(error_code), false); } if (r == RET_PF_RETRY) return 1; if (r < 0) return r; if (mmio_info_in_cache(vcpu, cr2, direct)) emulation_type = 0; emulate: //模拟指令 er = x86_emulate_instruction(vcpu, cr2, ...
VM中的应用发现页没有分片,MMU发起中断,从虚拟机的物理地址(QEMU的逻辑地址)中分配一页,然后更新页表。 此时虚拟机页的物理地址还没对应物理内存的地址,所以触发了qemu进程在宿主机的page fault。宿主机内核分配内存页,并更新页表。 下次访问就可以借助EPT来进行,只需要查两次表即可。
由于物理MMU只能通过Host机的物理地址(Host Physical Address, HPA)进行寻址,所以实现内存虚拟化,关键是需要将Guest机的虚拟地址(Guest Virtual Address, GVA)转换为HPA。传统的实现方案中,这个过程需要经历:GVAàGPAàHVAàHPA的转换过程,需要对地址进行多次转换,而且需要KVM的介入,效率非常低。为提供GVA到HPA的地址转换...
kvm_create_vm主要完成KVM虚拟机结构体的创建、KVM的MMU操作接口的安装、KVM的IO总线、事件通道的初始化等操作,主要流程如下: kvm_arch_create_vm()初始化kvm结构体; hardware_enable_all(),针对每一个CPU,调用kvm_x86_ops中硬件相关的函数进行硬件使能,主要设置相关寄存器和标记,使CPU进入虚拟化相关模式中(如Inte...
Intel引入了硬件辅助内存虚拟化扩展页表EPT(Extend Page Table),AMD 的是嵌入页表NPT(Nested Page Table),作为CPU内存管理单元MMU的扩展,通过硬件来实现GVA、GPA到HPA的转换。如图6,首先Guest通过CR3寄存器将GVA转换为GPA,然后查询EPT将GPA转换为HPA。EPT的控制权在VMM上,只有CPU工作在Non-Root模式时才参与该内存转换...
(enable_ept); /* line 5862 */ cr2 = vmcs_readl(EXIT_QUALIFICATION); trace_kvm_page_fault(cr2, error_code); vcpu->arch.l1tf_flush_l1d = true; if (kvm_event_needs_reinjection(vcpu)) kvm_mmu_unprotect_page_virt(vcpu, cr2); return kvm_mmu_page_fault(vcpu, cr2, error_code, NULL...