x86的虚拟化资料很多,与之相对的arm的虚拟化的讲解较少,这几天通过查找arm的官方文档稍微对arm的虚拟化架构有些了解,记下来留给以后查看。
由于arm的虚拟化主要体现在armv8-a架构上,我们就只讲这个架构上的东西。下面就简称arm架构。
虚拟化技术包括cpu、memory和device的虚拟化,了解了这三个就基本涵盖了虚拟化各方面。在讲arm虚拟化方案之前我们先讲一下armv8的exception level。不同于x86在虚拟化方面提供了与之前架构正交的root和非root模式,arm在exception level上增加了一层el2来完成硬件辅助虚拟化。也就相应增加了一套寄存器,名称为xxx_el2。其中最重要的是HCR_EL2寄存器,它是负责对虚拟化进行配置的。
CPU虚拟化:
主要是让敏感指令能够实现trap and emulation。这包括访问ID寄存器,memory控制的寄存器,辅助寄存器还有wfi和wfe等。也就是实现一旦guest执行这些指令就会trap到el2。这些设置就在HCR_EL2寄存器上。比如设置HCR_EL2.WFI为1,guest在执行wfi指令时就会产生异常并route到el2,由异常表决定接下来执行什么处理。
memory虚拟化:
内存虚拟化需要在guest用户空间访问内存时执行两次转换,stage1 和stage2。其中stage1在guest中完成,stage2在hypervisor层完成。一般用户访问内存是虚拟内存,须由mmu转换成物理内存,但是在虚机中,经过一次mmu转换的地址只是guest的物理地址,也叫IPA,要得到物理地址还需经过二次mmu转换,那如何才能让虚机在得到IPA之后主动进行二次转换呢?这就又需要HCR_EL2出场了。HCR_EL2中第0位就是VM位,负责使能虚拟化,这一位一旦设置为1,那么相应的stage2转换就使能了。
device虚拟化:
设备虚拟化比较复杂,涉及较多的东西,我们这里就讲讲设备虚拟化最开始那一部分。由于虚拟机管理程序不可能让虚机真正的接触到设备,模拟在所难免,那么如何完成模拟呢?还是要trap然后模拟,只要能trap,模拟就不是问题。这trap的任务还是在HCR_EL2身上。一般地操纵硬件的方法无非就是写寄存器,所以只要guest写了设备的寄存器我们就让它trap并产生exception,然后再去handle就行了。上面的memory虚拟化已经保证一切虚拟使用的内存都要经过stage2,我的理解是一般的stage2是不会产生exception fault的,只会马上进入mmu转换的阶段,要想截获这个trap就要让它产生硬件fault,这又需要HCR_EL2了。我认为是HCR_EL2.PTW一旦设置成1,那么stage2的转换就会产生permission fault。这样就能在exception表中添加handler了。我在kernel的代码中没有找到关于PTW的设置,而在qemu中可以找到,这可以作为一个旁证,但是还没有发现确凿的证据,如果有高手知道的话希望告知一下。
想了解更多,请参考https://developer.arm.com/architectures/learn-the-architecture/armv8-a-virtualization