前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IOMMU(六)-post interrupt

IOMMU(六)-post interrupt

作者头像
惠伟
发布2022-04-28 17:45:32
1.8K1
发布2022-04-28 17:45:32
举报
文章被收录于专栏:虚拟化笔记虚拟化笔记

post interrupt

post interrupt是intel提供的一种硬件机制,不用物理cpu从root模式exit到non-root模式就能把虚拟中断注入到non-root模式里,大概实现就是把虚拟中断写到post interrupt descriptor,预定义了一个中断号,然后给non-root模式下的cpu发送这个中断,non-root模式下cpu收到这个中断触发对virtual-apic page的硬件模拟,从post interrupt descriptor取出虚拟中断更新到virtual-apic page中,虚拟机中读virtual-access page,就能取到虚拟中断,处理中断,然后写EOI,触发硬件EOI virtulization,就能把virtual-apic page和post interrupt descriptor中数据清除。

post interrupt descriptor的格式如下:

PIR总共256位,一位代表一个虚拟中断。ON代表预先定义的中断已经发出,如果已经为1就不要再发预先定义的中断了。SN代表不要再发中断。NV就是预先定义好的那个中断号,NDST就是物理CPU的local apic id。

vt-x post interrupt

VMCS中增加如下字段控制post interrupt。

kvm用post interrupt模式给vcpu注入中断,kvm修改这个vcpu的post interrupt descriptor,然后给这个vcpu所运行的物理cpu发送中断号是post interrupt notification vector的中断。kvm只用到了post interrupt descriptor中的ON,用到的notification vector存放在VMCS中而不是post interrupt descriptor中,主要是kvm运行在另一个物理cpu上,一个vcpu有没有运行,运行在哪个物理cpu上,这个vcpu可不可以接收中断,kvm很好判断,如果没有运行或者不能接收中断kvm在把虚拟中断存放在其它地方。

vt-d post interrupt

IOMMU硬件单元也可以借用post interrupt机制把passthrough设备产生的中断直接投递到虚拟机中,不需要虚拟机exit出来,不需要VMM软件介入,性能非常高。这种情况下设备产生的中断从原来interrupt remapping格式变成post interrupt格式,IRTE中内容也变了,它中存放post interrupt descriptor的地址和虚拟中断vector,物理中断到了IOMMU,IOMMU硬件单元直接把IRTE中的虚拟中断vector写到post interrupt descriptor中pir对应的位,然后给vcpu所在的物理cpu发送一个中断,中断号就是post interrupt descriptor中的NV。

一个passthrough给虚拟机的外设,虚拟机里driver给外设分配虚拟中断,qemu拦截到对外设pci config space的写,然后把虚拟中断更新到kvm的irq routing entry中,kvm再调用update_pi_irte把post interrupt descriptor地址和虚拟中断号更新到IRTE中。

代码语言:javascript
复制
update_pi_irte
  └─irq_set_vcpu_affinity
       └─intel_ir_set_vcpu_affinity
             └─modify_irte

vt-x posted interrupt就是另一个CPU更新了vcpu的post interrupt descriptor,发送一个ipi给vcpu运行的物理CPU。vt-d posted interrupt就是IOMMU硬件单元更新了vcpu的post interrupt descriptor。vt-x和vt-d post interrupt都不会导致vcpu运行的物理CPU从non-root模式exit到root模式,而且能把vcpu的中断注入到guest。但vt-d相比vt-x就弱智多了,一个vcpu有没有运行,运行在哪个物理cpu上,这个vcpu可不可以接收中断,或者vcpu从一个物理cpu迁移到另一个物理cpu,vt-d IOMMU都不能自己判断,只能通过kvm告诉它,所以kvm就把这些信息写到post interrupt descriptor的其它位中,IOMMU来读,这些位就是SN,NDST和NV。

vcpu转换为运行状态,vmx_vcpu_pi_load清除SN,更新NDST。

代码语言:javascript
复制
vcpu_load
  └─preempt_notifier_register

context_switch
  └─finish_task_switch
      └─fire_sched_in_preempt_notifiers
          └─ __fire_sched_in_preempt_notifiers
               └─kvm_sched_in
                   └─kvm_arch_vcpu_load
                      └─kvm_x86_vcpu_load
                           └─vmx_vcpu_pi_load

vcpu暂时挂起,设置SN。

代码语言:javascript
复制
vmx_vcpu_put
    └─vmx_vcpu_pi_put

虚拟机执行hlt指令vcpu暂停,保留原先运行的物理cpu到NDST,设置NV为wakeup vector

代码语言:javascript
复制
vcpu_block
    └─vmx_pre_block
         └─pi_pre_block

如果此时IRTE中URG为1,IOMMU就给物理cpu发送wakeup vector,pi_wakeup_handler让vcpu开始运行。

代码语言:javascript
复制
DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_posted_intr_wakeup_ipi)
{
	ack_APIC_irq();
	inc_irq_stat(kvm_posted_intr_wakeup_ipis);
	kvm_posted_intr_wakeup_handler();
}
kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler);

vcpu开始运行,更新NDST,理想NV为post interrupt vector。

代码语言:javascript
复制
vmx_post_block           
  └─pi_post_block

pv ipi

虚拟机中一个vcpu要向另一个vcpu发送ipi或者向其它vcpu广播ipi,怎么利用post interrupt?

首先源vcpu需要把ipi的目的vcpu的local apic id写到apic寄存器,再写icr寄存器,写icr寄存器就会导致vcpu exit,然后kvm就可以利用vt-x posted interrupt把虚拟中断注入到另一个vcpu。如果是广播ipi,那么源vcpu要exit出来很多次。

代码语言:javascript
复制
kvm_lapic_reg_write->kvm_apic_send_ipi

所以腾讯云李万鹏就想了招,通过hypercall传bitmap一次把所有目的vcpu都传出来,这样源vcpu就可以少exit出来几次。

代码语言:javascript
复制
kvm_emulate_hypercall->kvm_pv_send_ipi

有些虚拟机中的业务会大量用到ipi,导致虚拟机exit出来很多很多次,性能影响太大。有人就想到把源vcpu所运行的物理cpu的lapic的icr寄存器透传给vcpu,把其它vcpu的post interrupt descriptor也透传给虚拟机源vcpu,源vcpu要给目的vcpu发送ipi,源vcpu修改目的vcpu的post interrupt descriptor,源vcpu给真正的硬件寄存器icr写post interrupt notification vector,这样源vcpu不用exit出来。问题就是有点不安全,一个有问题的虚拟机可以频繁给其它物理cpu发送ipi,造成其它物理cpu ipi DDOS攻击,私有云可以用,公有云不行。

参考文献

Intel SDM 3c

Intel vt-d spec

https://dl.acm.org/doi/abs/10.1145/3381052.3381317

https://patchwork.kernel.org/project/kvm/patch/0C23CC2D-B770-43D0-8215-20CE591F2E8F@bytedance.com/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • post interrupt
  • vt-x post interrupt
  • vt-d post interrupt
  • pv ipi
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档