我个人以为,在一台物理机器上运行虚拟机器,并且虚拟机器还和物理机器公用一套硬件,最复杂的东西只有两个,那就是内存管理和中断管理,对于内存管理,影子叶表已经解决了绝大多数的问题,对于中断问题,还有很多的不同的解决方案有待选择。
以x86系列处理器为例,当中断发生的时候,总是会有intr信号发送到cpu的,如果此时正在运行的是guest os的话既然guest os运行在ring1,那么很显然vmm会捕获到这个信号,那么既然vmm捕获到了这个信号,那么它肯定有办法将此信号转交于host os的中断处理程序,至于怎么转发,我想这不是问题,因为每一个设计者都会很好的处理这个问题的,有时间的话看看《设计原本》这本书吧!具体的技术细我我们不需要关注,最重要的是我们必须有一种我们自己的风格,这就是设计!,ring0可以捕获到ring1的操作,那么ring0就可以模拟ring1的任何操作。
下面是自我构思的一个vmm处理硬件中断的过程。设起初,机器在guest os中的用户态执行,突然间来了中断:
1.机器进入ring0,由于涉及了ring的切换,ss,esp,cs,eip均进行了切换,从guest os切换到了vmm
2.由于vmm映射了自己的idt,跳转到了vmm的中断处理程序
3.在vmm的中断处理程序中,将中断号记录在了vmm和host os共享的cross page中。
4.在host os的idt中查找中断向量n对应的处理地址,并且设置host os的cs,eip为此处理程序,并且将原始的host os保存的上下文(cs,eip,ss,esp)压入保存的host os的内核堆栈
5.切换回host os,自然跳入host os的中断处理程序
6.中断处理完毕,iret返回之前,决策调度,如需调度,则下列序列执行延迟,再次调度于此时执行,若否,则继续
7.iret返回,由于第四步压入堆栈的上下文,返回host os继续执行,vmx86run返回到host os vmware-vmx的用户空间,以后进入传统的轨道。
8.如再次切换到guest os,那么从2,3处的guest os上下文开始执行
由此可见,中断执行涉及的上下文切换异常消耗巨大,然而,如果不理清这个处理过程,再高效的事情又从何谈起呢?
本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271122