Armv8-A 虚拟化
参考文献:Armv8-A virtualization.pdf
Arm中,常使用的虚拟机监视器有Xen(type1)和KVM(type2)。
- 全虚拟化和半虚拟化
全虚拟化是指一般的虚拟机,它可以完全模拟物理机器。但性能差,每次对寄存器的操作都得经过监视器。
半虚拟化是为了提升性能的,如Guest OS,它好像运行在一个虚拟硬件平台上。
- 虚拟机和虚拟CPU
- AArch64下的虚拟化
Stage 2 translation
Stage 2 translation允许监视器控制VM的内存视图。可确保一个VM只能看到分配给它的资源。
客户机OS控制着Stage 1 Tables,自认为控制了物理地址空间。然而,还有第二个阶段的地址转换,这是由监视器控制。
每个VM都有一个虚拟机标识符VMID,这样在TLB里可以通过VMID来区分不同的VM对应的表项。
同时,TLB表项中还会有一个ASID标识符(Address Space Identifier),它标识不同的应用,防止不同应用相互干扰。每个VM有自己独立的ASID命名空间。即使ASID相同,但VM不同,它们也不会互相影响。
- 属性合并和覆盖
阶段1和阶段2的映射都包含一些属性,比如类型和权限。MMU会合并这两个映射的属性,得到最终的属性值。MMU使用两个阶段里最严格的属性。
模拟内存映射IO
一个VM的IPA空间包含内存和外设区域。VM的外设可以是虚拟外设,也可以是真实外设(直通设备)。
- 真实外设
如果是直通设备,也就是一个真实的物理设备真的分配给了VM,并直接映射到了IPA地址空间。因此VM可以直接访问外设。
- 虚拟外设
虚拟外设是指hypervisor模拟出来的外设。当VM访问外设对应IPA地址空间的位置时,会产生abort,之后交由hypervisor完成访问,之后异常返回。
系统MMU(SMMU)
对于其他IO方式,例如DMA,它有一个DMA控制器。对于VM来讲,系统结构图是这样的:
如果让监视器来实现DMA的两阶段映射的话,会带来额外的性能开销。解决办法就是IOMMU,又叫做SMMU。这样DMA看到的内存,与VM(OS级)看到的物理内存,是一样的了。
通过trap模拟特定指令的执行
如果客户机想要执行一些特权指令,那么监视器应该能捕获到这种指令,并来模拟该指令去修改,这样可以保证安全性。
例如执行Wait For Interrupt(WFI)指令可以让CPU处于低功耗状态。当EL0或EL1时执行WFI,发生trap交由hypervisor来处理。
注意,客户机的程序执行流也是在真实CPU上跑的,不同EL级的差别在这些CPU寄存器的配置位不同
当客户机想读取一个寄存器,而Hypervisor想呈现一个不同的值,叫做虚拟值。这时就可以发生trap到EL2级,hypervisor返回时呈现一个自定义的值给客户机。
异常的虚拟化
使用虚拟化的系统,一些中断可能被hypervisor自己来处理,一些可能由VM的软件来处理。为了避免出现VM此时没有被调度但针对该VM的中断发生的情况,ARM采用了两个机制:
- 一些中断支持在EL2级被hypervisor解决
- 其他中断能交给对应的VM或vCPU
为了实现这2种机制,ARM包含了对虚拟中断的支持:vIRQ和vFIQ。这两种中断只能在当执行El0和El1发生。
VM通常只会接受虚拟中断,而不是真实中断。
- 允许虚拟中断
设置HCR_EL2.IMO位,即可开启vIRQ等虚拟中断
- 产生虚拟中断
有2种机制可以用来产生虚拟中断。
a. 通过设定HCR_EL2寄存器的3个特定位VI、VF、VSE来产生一个对vCPU的中断信号。这样由hypervisor来模拟产生中断,会带来额外运行开销。
b. 使用GIC产生虚拟中断。GIC通过两套相同的接口来产生真实和虚拟中断。hypervisor可以将虚拟CPU接口映射到VM,实现VM和GIC的直接通信,从而不需要hypervisor来模拟中断
- 一个例子
假设使用GIC来产生虚拟中断。一台物理外设连接GIC,当物理外设发出中断信号时,交由GIC处理,之后的步骤如下图所示:
标签:虚拟化,中断,hypervisor,VM,学习,虚拟,Armv8,外设 From: https://www.cnblogs.com/fyqs/p/17575143.html