本文将记录一些对posted interrupt的思考。

本文参考的内核版为v5.18

1. irqfd亦可使用posted interrupt

irqfd其实也可以使用VT-x posted interrupt来避免interrupt acceptance的一次VM Exit。

1.1 kvm_arch_set_irq_inatomic

QEMU写了irqfd后,KVM内核模块中的irqfd poll就收到一个POLL_IN事件,然后将MSIx中断自动投递给对应的LAPIC。 大致流程是:POLL_IN -> kvm_arch_set_irq_inatomic -> kvm_set_msi_irq, kvm_irq_delivery_to_apic_fast

kvm_arch_set_irq_inatomic最终会调用kvm_irq_delivery_to_apic_fast来给guest注入interrupt。

1.2 kvm_irq_delivery_to_apic_fast

1
2
3
4
5
6
kvm_irq_delivery_to_apic_fast
└── kvm_apic_set_irq
└── __apic_accept_irq
└── vmx_deliver_interrupt
└── vmx_deliver_posted_interrupt
└── kvm_vcpu_trigger_posted_interrupt

2. __apic_accept_irq

__apic_accept_irq其实就会使用VT-x的posted interrupt完成中断的注入。

KVM_SIGNAL_MSIKVM_IRQ_LINE等ioctl其实会在KVM中调用__apic_accept_irq函数,因此,最终会使用到posted interrupt来完成虚拟中断的注入。

根据我的理解(待实验验证),在VNC中的鼠标键盘操作,其实本质上是给虚拟机注入中断,对于这种中断,也是可以使用posted interrupt的。

3. 在虚拟化下,lapic timer可以用VT-x posted interrupt呢?

在虚拟化场景下,假设vCPU与pCPU一一绑定,那么,lapic timer可以使用VT-x posted interrupt吗?
在KVM架构下,答案是否定的,分析如下:

当前是设置了External-interrupt exiting这个位的。当vCPU在non-root mode,此时物理的lapic timer的中断来了,那么就会导致VM Exit,此时使用VT-x posted interrupt已经没有意义了。

Injection Exitless LAPIC Timer的Idea是offload lapic timer to housekeeping cpus,然后由housekeeping cpu利用VT-x posted interrupt为vCPU注入中断!

ps:如果vCPU的lapic timer由preemption timer进行模拟的话,定时器到期后vCPU会陷出,此时也没有必要用posted interrupt了。

4. WNV的发送in VT-d

new.nv = POSTED_INTR_WAKEUP_VECTOR

当vCPU处于ready-to-run或者halted状态时,物理中断来了,此时IOMMU会发送WNV来唤醒vCPU
值得注意的是: WNV是IOMMU发送的,而非软件。


参考资料:

  1. Virtio Spec Overview
  2. Broiler Interrupt Virtualization Technology
  3. QEMU 如何模拟中断
  4. QEMU学习笔记——中断
  5. QEMU 如何处理PCI设备的中断(二)
  6. kvm post interrupt