VT-d Posted Interrupt
本文将介绍VT-d Posted Interrupt的相关内容。首先会以一个例子介绍Posted interrupt的motivation;然后详细阐述涉及到的硬件和软件细节;接下来会介绍不同vCPU状态下的差异化处理;最后总结下本文。
阅读本文前,需先阅读以下文章:
- Intel SDM Chapter 29: APIC Virtualizaton & Virtual Interrupts
- Introduction to VT-x Posted-interrupt
- VT-d Interrupt Remapping
1. terms
- PI(Posted Interrupt)
- hv(hypervisor)
- VM(Virtual Machine)
- IRTE(Interrupt Remapping Table Entry)
- PID(Posted Interrupt Descriptor)
- PIR( Posted Interrupt Requests)
- ON(Outstanding Notification)
- NV(Notification Vector)
- ANV(Active Notification Vector)
- WNV(Wake-up Notification Vector)
- ple(pause loop exiting)
2. motivation
在VT-d Interrupt Remapping demo usage中,如果目标vCPU正在运行,但是,当物理CPU接受到physical interrupt时,需发生VM-Exit,由hv为guest注入vector为30的virtual中断。
思考下:是否可以省去如下步骤:当物理CPU接受到physical interrupt时,需发生VM-Exit,由hv为guest注入vector为30的virtual中断。由硬件为正在运行的vCPU直接注入vector为30的virtual 中断(这样避免了一次VM-Exit),而这正是VT-d PI所能完成的功能。
3. details
3.1 CAP_REG的PI位
IOMMU通过Capability Register(CAP_REG)的PI位来报告interrupt posting capability。
3.2 IRTE
VT-d PI是VT-d Interrupt Remapping的一个扩展功能。根据Interrupt Remapping可知, 所有的Remapping格式中断请求都需要通过中断重映射表来投递, IRTE中的Mode域(IM)用来指定这个remappable中断请求是interrupt-remapping方式还是interrupt-posting方式。
如果IRTE的IM位为1,则VT-d硬件将会以PI的形式来解析该IRTE,如下图所示:
需要关注PI格式的IRTE的以下几个field:
- Posted Descriptor Address Low/High,该区域保存一个指向内存的指针,该指针指向的位置就是PID。
- Urgent位,该位用于表示该中断是否是紧急的,即是否需要目标CPU立即响应。
- Vector用于指定PID.PIR中哪个bit要置位。
3.3 PID
每个PID的大小为64 Byte,直接被硬件用来记录将要post的中断请求。其格式如下所示:
- Posted Interrupt Request (PIR)域,一共256 bit,每个bit对应一个中断向量,当VT-d硬件将中断请求post过来的时候,IRTE.Vector对应的bit将会被置起。
Outstanding Notification (ON)域,表示该PID当前是否已经发出了一个Notification Event等待CPU的处理。
当VT-d硬件将中断请求记录到PIR的时候,如果ON为0,并且允许立即发出一个Notification Event时,则将会将ON置起来,并且产生一个Notification Event;如果ON已经被置起来,则不会产生一个Notification Event。
ON的清零。
- Suppress Notification (SN)域,表示当PIR寄存器记录到non-urgent的中断时,是否不发出Notification Event,如果该位为1,则当PIR记录到non-urgent中断的时候,不发出Notification Event,并且不更改Outstanding Notification位的值。
- Notification Vector (NV)域,表示如果发出Notification Event时,具体的Vector值。
- Notification Destination (NDST)域,表示如果发出Notification Event时,要传递的物理CPU的LAPIC ID。
3.4 硬件上Posted Interrupt的处理过程
PST即IRTE中的Interrupt Mode位。
当VT-d硬件接收到其旗下I/O设备传递过来的中断请求时,会先查看自己的中断重定向功能是否打开,如果没有打开则,直接上传给LAPIC。如果中断重定向功能打开,则会查看中断请求的格式,如果是不可重定向格式,则直接将中断请求提交给LAPIC。如果是可重定向的格式,则会根据算法计算Interrupt_Index值,对中断重定向表进行索引找到相应的IRTE。然后,查看IRTE中的Interrupt Mode,如果为0,则该IRTE的格式为Remapped Format,即立即根据IRTE的信息产生一个新的中断请求,提交到LAPIC。如果Interrupt Mode为1,则表示该IRTE的格式为Posted Format,根据IRTE中提供的PID的地址,在内存中找到相应PID,并根据其ON、URG和SN的设置判断是否需要立即产生一个Notification Event,如果不需要,则只是将该中断信息记录到PID.PIR中,等待hv的后续处理(会在vCPU is ready-to-run or halted when Notification Event happen中介绍)。如果需要立即产生一个Notification Event,则根据PID(会提供目标APIC ID、vector、传输模式和触发模式等信息)产生一个Notification Event,同时将ON置位。
硬件在对PID进行修改的时候,要保证该修改是原子操作,即对PID的读取、修改和写入必须是原子操作,并且在写入之后,要保证相应内存在各个cache agent之间的一致性,即所有的CPU应该立马能够看到该内存修改。
3.5 the relationship with VT-x Posted-interrupt
VT-x Posted-interrupt需要与IOMMU协同工作才能实现VT-d Posted Interrupt feature。
有三点需要注意:
- enable APICv
- 设置VMCS的posted-interrupt descriptor,这正是IRTE中Posted Descriptor Address Low/High所设置的值。
- 设置VMCS的posted-interrupt notification vector为ANV(下节会详细介绍)。
4. 不同vCPU状态下的差异化处理
4.1 Background
在vCPU调度的过程中,vCPU会有如下三种状态:
- 当vCPU被scheduler选中来运行的时候,此时vCPU的状态为’active’。
- 当vCPU被抢占(Preempted),例如时间片到期了,此时vCPU的状态为’ready-to-run’。
- 当vCPU执行了
hlt
指令或者触发了ple,hv也会干预进来将vCPU给block出来,此时vCPU状态为’halted ‘。
4.2 ANV and WNV
hv需要为每个vCPU分配物理中断vector:
第一个称作Active Notification Vector(ANV),该Vector对应到vCPU的状态为active时,Notification Event所使用的中断vector(需要设置VMCS的posted-interrupt notification vector为ANV)。
第二个称作Wake-up Notification Vector(WNV),该Vector对应到目标vCPU不在当前物理CPU上执行时,由于Urgent被置起来产生的Notification Event所使用的中断Vector。
在active状态下,PID.NV的值就是ANV。在ready-to-run或者halted状态下,PID.NV的值就是WNV。这里的ANV和WNV可以是同一个值。
hv需要保证的是:运行在同一个pCPU上的所有vCPU的PID.NV值不同。
详情可参考:ACRN posted interrupt
4.3 vCPU Scheduling
只需理解状态转换,对于‘NV’的设置是hv specific的,无需深究。
4.4 vCPU is active when Notification Event happen
guest在Non-Root下就能直接处理此中断,而不需要hv的参与。
详细步骤请参考:Posted Interrupt
4.5 vCPU is ready-to-run or halted when Notification Event happen
WNV的handler:
如果vCPU的state为halted,则需要先将vCPU的状态设置为ready-to-run。
handler会调度vCPU。
扫描PID.PIR,检测是否有处于pending状态的posted interrupt请求;如果有处于pending状态的posted interrupt请求,hv会在LAPIC上生成一个vector号为ANV的self-IPI(注意:在还未真正enter guest之前,当前物理CPU处于关中断状态)。 当进入Non-Root模式时,物理IRR寄存器中的ANV位会被置上,硬件(CPU)会处理posted interrupt。该中断的处理类似于vCPU处于active状态时,接收到了ANV的中断请求,vCPU可以直接对其进行处理,不需要hv的参与。
5. summary
VT-d PI advantages
- External interrupts from direct-assigned devices are delivered to guest running in non-root mode directly
- Improve Interrupt virtualization efficiency, e.g. Less VM-Exits.
- Simplify interrupt migration
- 更新PID.NDST
- 如果per-PCPU的IDT向量管理不一样,还需要更新PCPU IDT的vector
- Consume less physical interrupts
参考资料: