AMD Secure Virtual Machine对虚拟化技术的支持是多方面的,除了IOMMU,Tagged TLB外,另外还有可选的Nested Paging以及VMRUN/VMEXIT指令等(Intel也有类似的实现)。
如果没有Nested Page Tables(NPT),hypervisor对guest OS中的每一个页表(gPT)都要维护一个shadow page table(sPT),硬件实际使用的是hypervisor提供的sPT。gPT是写保护的,因此guest OS对gPT进行操作时,例如删除,更新等,就会发生page fault,然后由hypervisor接手对gPT进行修改,最后同步sPT。另外一种实现是让guest OS操作gPT,等真正发生了page fault,再由hypervisor同步sPT。
NPT需要两级地址转换。第一级是guest linear address到guest physical address,guest CR3(gCR3)指向其页表地址。第二级是guest physical address到host physical address,nested CR3(nCR3)指向其页表地址。gCR3本身就是guest physical address,这个地址首先要经过NTP转换为host physical address。接下来每次由guest page talbe得到的地址都要经过NPT的转换得到host physical address。TLB中最终存储的是guest linear address到host physical address的转换结果。
每个guest OS只有一个NPT,hypervisor不需要为每个gPT维护一个sPT,因此会节省大量物理内存。其次guest OS可以操作自己的gCR3,这样进程切换不再需要hypervisor的参与,而虚拟机的性能瓶颈主要就是guest OS和hypervisor之间的频繁切换。
早期的x86处理器由用户态陷入内核态唯一的方法就是通过中断,也就是系统调用,如0x80号中断。后来为了加速这个过程,Intel引入了SYSENTER和SYSEXIT指令,AMD引入了SYSCALL和SYSRET指令。这些指令使操作系统在ring 0和ring 3之间,也就是内核态和用户态之间快速切换。如果hypervisor驻留在ring 0,guest OS驻留ring 1,应用程序驻留ring 3,guest OS将不能驻留在传统的ring 0上,而SYSCALL/SYSRET指令只能在ring 0下执行,那么用户态和内核态之间的切换就只能通过中断。
支持虚拟化的处理器已经引入了比ring 0更高的特权级,我们可以叫做ring -1。为了加快ring 0和ring -1之间的切换AMD引入了VMRUN和VMEXIT指令。这两个指令可以类比SYSCALL和SYSRET。SYSCALL保存用户态当前的信息以便从内核态返回后继续执行。VMRUN和VMEXIT同理,只不过它们保存和恢复的是guest OS的运行状态。
参考资料:
A Comparison of Software and Hardware Techniques for x86 Virtualization
The Definitive Guide to the Xen Hypervisor
AMD64 Architecture Programmer’s Manual Volume 2: System Programming(15 Secure Virtual Machine)
AMD-V™ Nested Paging
阅读(4114) | 评论(2) | 转发(0) |