文章目录
Virtualizing exceptions
中断被系统中的硬件用来向软件发送事件信号。例如,GPU可能会发送一个中断,以发出它已经完成渲染帧的信号。
使用虚拟化的系统更为复杂。有些中断可能由hypervisor本身处理。其他中断可能来自分配给虚拟机(VM)的设备,并且需要由该VM内的软件处理。此外,被中断作为目标的VM在接收到中断时可能没有运行。
这意味着您需要一些机制来支持hypervisor对EL2中某些中断的处理。您还需要将其他中断转发到特定VM或VM中的特定虚拟CPU(vCPU)的机制。
为了启用这些机制,该体系结构包括对虚拟中断的支持:vIRQ、vFIQ和vSErrors。这些虚拟中断的行为与物理中断(IRQ、FIQ和SErrors)类似,但只能在EL0和EL1中执行时发出信号。在EL2或EL3中执行时,不可能接收到虚拟中断。
概括地说,Armv8.4-A中引入了对安全状态下虚拟化的支持。为了在安全EL0/1中发出虚拟中断信号,需要支持并启用安全EL2。否则,虚拟中断不会在安全状态下发出信号。
Enabling virtual interrupts
要向EL0/1发送虚拟中断信号,hypervisor必须在HCR_EL2中设置相应的路由位。例如,要启用vIRQ信令,hypervisor必须设置HCR_EL2.IMO。此设置将物理IRQ异常路由到EL2,并启用虚拟异常到EL1的信令。
虚拟中断按中断类型进行控制。理论上,VM可以被配置为接收物理FIQ和虚拟IRQ。在实践中,这是不寻常的。虚拟机通常只配置为接收虚拟中断。
Generating virtual interrupts
有两种机制用于生成虚拟中断:
- 通过core内部,使用HCR_EL2中的控件。
- 使用GICv2或更高版本的中断控制器。
让我们从机制1开始。HCR_EL2中有三个位控制虚拟中断的生成: - VI=设置此位将注册一个vIRQ。
- VF=设置此位注册一个vFIQ。
- VSE=设置此位会注册一个vSError。
设置这些位中的一个相当于中断控制器向vCPU断言中断信号。生成的虚拟中断要接受PSTATE屏蔽,就像常规中断一样。
这种机制使用起来很简单,但缺点是它只提供了一种生成中断本身的方法。然后需要hypervisor来模拟虚拟机中中断控制器的操作。概括地说,最好避免软件中的捕获和模拟操作涉及的开销对于频繁的操作(如中断)。
第二个选项是使用Arm的通用中断控制器(GIC)来生成虚拟中断。通过Arm GICv2,GIC可以通过提供物理CPU interface和虚拟CPU interface来发出物理和虚拟中断信号,如下图所示:
这两个接口是相同的,只是其中一个发出物理中断信号,另一个发出虚拟中断信号。hypervisor可以将虚拟CPU interfaces映射到虚拟机中,从而允许该虚拟机中的软件直接与GIC通信。这种方法的优点是,hypervisor只需要设置虚拟接口,而不需要对其进行仿真。这种方法减少了需要将执行捕获到EL2的次数,从而减少了虚拟化中断的开销。
尽管Arm GICv2可以与Armv8-A设计一起使用,但更常见的是使用GICv3或GICv4。
Example of forwarding an interrupt to a vCPU
到目前为止,我们已经研究了如何启用和生成虚拟中断。让我们看一个示例,它显示了将虚拟中断转发到vCPU。在本例中,我们将考虑已分配给VM的物理外围设备,如下图所示:
该图说明了这些步骤:
- 物理外围设备将其中断信号断言到GIC中。
- GIC生成一个物理中断异常,IRQ或FIQ,通过HCR_EL2.IMO/FMO的配置将其路由到EL2。hypervisor识别外围设备并确定其已分配给VM。它检查中断应该被转发到哪个vCPU。
- hypervisor配置GIC将物理中断作为虚拟中断转发给vCPU。然后,GIC将断言vIRQ或vFIQ信号,但处理器在EL2中执行时将忽略该信号。
- hypervisor将控制权返回给vCPU。
- 现在处理器在vCPU(EL0或EL1)中,可以从GIC获取虚拟中断。此虚拟中断受PSTATE异常掩码的约束。
该示例显示了作为虚拟中断转发的物理中断。该示例与第2阶段翻译部分中描述的指定外围模型相匹配。对于虚拟外设,hypervisor可以创建虚拟中断,而无需将其链接到物理中断。
Interrupt masking and virtual interrupts
在AArch64异常模型指南中,我们在PSTATE、PSTATE.I(用于IRQ)、PSTATE.F(用于FIQ)和PSTATE.A(用于SErrors)中引入了中断掩码位。当在虚拟化环境中操作时,这些掩码的工作方式略有不同。
例如,对于IRQ,我们已经看到设置HCR_EL2.IMO有两件事:
- 将物理IRQ路由到EL2。
- 启用EL0和EL1中vIRQ的信令。
此设置也会更改PSTATE.I掩码的应用方式。而在EL0和EL1中,如果HCR_E2.IMO==1,PSTATE.I对vIRQ而不是pIRQ进行操作。