KVM中断系统结构关系

Windows 21NN.CN 3个月前 (08-13) 10次浏览 已收录 0个评论 扫描二维码

KVM 中断系统结构关系

现在,KVM虚拟机的中断是在KVM内核模块中实现的(一般我们都是这么使用的),理解数据结构就可以了解一个软件是如何实现的,所以本博文就来对虚拟中断子系统所涉及的数据结构进行梳理,给大家一个中断系统直观简单的感受。这里不多介绍apicv PI以及vt-d PI,以后博文再介绍,也可以直接请教Intel OTC的中断大牛WuFeng同学(邮件地址去邮件列表里面去搜索,姓氏在名字之后,别说我告诉你,哈哈哈)

1. 硬件基本知识

简单介绍点硬件知识,方便后面的讲解

最老的中断控制芯片就是8259A了,也就是PIC芯片,该种芯片8个引脚,为了扩展引脚数目,引入了主从两块芯片,利用一个引脚连接主从两个芯片,这样就一共有15个引脚了。IRQ = 其实base号 + pin。接收到设备中断后,通过拉高引脚通知CPU,CPU收到中断发送两个INT ACK到INTA,第二个INTA期间,PIC向CPU提交中断vector。

后来出现了APIC,APIC分为IOAPIC和LAPIC。IOAPIC位于南桥,有24个引脚针,LAPIC位与CPU内部。LAPIC每CPU一个;IO APIC可以一个系统里面有多个,但是KVM中只实现了一个,可以根据自己的需要进行添加。设备发送中断,发送到IO APIC;IO APIC中存在着一个PRT表,每个PRT的表项成为RTE,RTE是每个引脚一个,IOAPIC引脚收到中断消息后,根据RTE得到目标LAPIC,并格式化出一个中断消息发送给LAPIC,同时置位remote irr(level)。LAPIC接受到中断消息后,提取其中的VECTOR并设置IRR后,进行中断的选取,取得优先级最高的中断后,清除IRR,设置ISR,提交CPU进行中断处理,CPU处理完中断后,写LAPIC的EOI,通知IOAPIC清除remote irr(level且deassert)。

后来又出来的MSI中断,设备直接如果支持MSI的话,直接构造出MSI消息,MSI有个字段Address标明了中断目标地址,然后设备直接发送中断给LAPIC提交CPU,这种方式下,直接绕过了IOAPIC,效率更高。

这里需要额外说明一下,中断的触发方式分为level触发和edge触发;level触发就是一直将引脚保持在高电平(电平为1)直到中断完成,现在PCI/PCIE设备都是level触发;edge就是通过一个电平边缘跳变来触发的中断,电平从0到1,或者从1到0,原来的ISA设备都是edge触发,kvm中通过发送level = 0和level = 1的两个中断来模拟一个edge中断。

GSI 是ACPI 引入的概念,全称是Global System Interrupt。它为系统中每个中断源指定一个唯一的中断号。如果GSI base 为0,每个管脚的GSI=GSI base + pin,15以上的GSI号和IRQ值相等,但是[0~15]是按照规范映射的,其实试试GSI 2映射到了IRQ 0上了,在KVM中引脚号就是IRQ号。

2. 虚拟中断子系统逻辑图

KVM中断系统逻辑图如下

KVM中断系统结构关系vcW6zUdTSbXE07PJ5LnYz7WjrNXi0Km2vMrHus3QvsaswODQzc7eudi1xKOsvt/M5bXE0L7GrLa8yse8zLPQus3Ktc/WvdO/2qOs0OnE4snosbi1xNbQts+3osvNuPhJUlEgQ0hJUL3Tv9q/qsq81tC2z7XExKPE4qO7t9ax8Mq1z9bBy1BJQ6GiSU9BUElD0tS8sE1TSbXEc2V0t723qL340NCjrM2ouf1zZXS3vbeozeqzybbU09pWQ1BVtcTW0LbP16LI66GjxuTW0ElPQVBJQ9bQttTT2sO/uPbS/b3Fo6zT1rao0uXBy1BSVKOsSU9BUElDytW1vdbQts+687j5vt1SVEUmIzI2Njg0O8q9u6+z9tbQts/P+8+isqK3osvNuPjEv7HqTEFQSUOjrExBUElDzeqzydbQts+1xNGhvtm6zdeiyOvKtc/WoaM8L3A+CjxwPjwvcD4KPHA+PHN0cm9uZz4zINDpxOLW0LbP19PPtc2ztcS52M+1PC9zdHJvbmc+PC9wPgo8cD48L3A+CjxwPtXiuPbQob3aztLDx8C0v7S/tEtWTbXEvt/M5cq1z9ahozwvcD4KPHA+PC9wPgo8cD4zLjE8c3Ryb25nPklSUbPpz/O907/asuM8L3N0cm9uZz48L3A+CjxwPjwvcD4KPHA+PGltZyBzcmM9″http://www.2cto.com/uploadfile/Collfiles/20161111/20161111092027172.png” alt=”\”>

KVM中irq_routing指向了IRQ CHIP抽象接口的表kvm_irq_routing_table结构体。

kvm_irq_routing_table .chip每个成员对应一个引脚,内容记录了该引脚的GSI号,其实该成员已经不用了。kvm_irq_routing_table.map成员指向一个hash桶,桶上的每个元素对应一个抽象引脚,即每个链对一个IRQ号,链上的每个元素指向kvm_kernel_irq_routing_entry结构体,每个该结构体代表了一个具体芯片的set()方法的实现,在进行中断注入的时候,每种芯片的set方法都会被调用一下,在guest中会忽略没有实现的芯片类型发送的中断消息(其实这里是可以优化的,必经不需要多次的中断注入,在QEMU注册中断设备的时候就不要注册不需要的中断芯片类型)

kvm_kernel_irq_routing_entry结构体对应具体芯片的一个引脚,按照芯片类型实现kvm_kernel_irq_routing_entry.set接口,kvm_kernel_irq_routing_entry.chip成员记录了该结构体对应的具体是哪种芯片的那个引脚,kvm_kernel_irq_routing_entry.gsi记录了该引脚的gsi号。

可以参考kvm_set_routing_entry()、kvm_set_irq()函数

3.2PIC 芯片结构

KVM中断系统结构关系

PIC是系统一个,由kvm.arch.vpic成员指向

Kvm_pic结构体就是虚拟PIC的实现dev_master、dev_slave、dev_eclr实现了虚拟PIC设备的PIO地址空间,并注册在KVM内核的PIO总线上,以便完成设备的IO操作,这个我会在后面的博文中对大家介绍,ECLR就是控制中断触发方式的寄存器; pics执行一个数组,每个元素指向kvm_kpic_state结构体,kvm_kpic_state结构体芯片的所有寄存器和状态,包括IRR,ISR,IMR等

3.3IOAPIC芯片结构

KVM中断系统结构关系

IOAPIC在KVM实现中只有一个,由kvm.arch.vioapic指向kvm_ioapic结构体。

kvm_ioapic结构体就是虚拟IOAPIC。irr成员就是IRR寄存器。redirtbl[IOAPIC_NUM_PINS]是一个数组,构成PRT表,每个成员对一个IOAPIC的引脚,执行kvm_ioapic_redirect_entry结构体。

kvm_ioapic_redirect_entry结构体就是一个RTE,fields成员执行了RTE中的各个域,如dest_id和dest_mode用来确定目标CPU,vector用来确定中断向量号,remote_irr在level触发时候保证中断共享情况下可以处理到所有设备的中断请求。Fields和kvm_kernel_irq_routing_entry的gsi配合起来确定了一个完整的中断信息内容

3.4XXOO

3.5LAPIC芯片结构体

KVM中断系统结构关系

LAPIC是每个VCPU一个,由kvm.vcpus[i].arch.apic指向kvm_lapic结构体。

kvm_lapic结构体代表一个虚拟LAPIC。base_address为LAPIC的基地址,这是一个GPA,是GUEST设置的LAPIC的基地址,在GUEST写某个LAPIC寄存器的时候,会带入该寄存器的GPA”,然后GPA’减去base_address可以算出寄存器对于基地址的偏移量,然后到regs成员中真正的找到虚拟寄存器加以修改,请参见apic_mmio_read,apic_mmio_write;dev成员将lapic在KVM内核空间的KVM MMIO BUS总线上注册了IO地址空间,通过对IO地址空间的操作完成对LAPIC的操作。regs成员指向一个页面,这是一个HVA,指向一个HOST的页面,这个页面总记录了LAPIC是所有虚拟寄存,IRR,ISR,LVT等等,通过偏移量就可以得到某个虚拟寄存器的HVA,完成对该虚拟寄存器的读写操作。

kvm_lapic_irq结构体是中断经过IOAPIC的PRT格式化出来的中断消息,从IOAPIC发送给LAPIC。

LAPIC在GUEST运行之前会对IRR中的进行选举,找到最高优先级的中断,该中断会被记录在kvm_queued_interrupt结构体中并且pending成员设置为true;nr成员记录了该中断的中断向量号,soft说明是否是硬中断。如果该中断大于PPR,就进行注入。如果注入成功,在虚拟机退出的时候,将pending设置为false,这个结构体保存着kvm.vcpus[i].arch.interrupt中。如果注入不成功,会在再次进入虚拟机的时候再次进行注入。

为了加速对于目标VCPU的查找,在kvm.arch.apic_map中保存了kvm_apic_map结构体。phys_map成员和logical_map成员记录了RTE的destination filed同VLAPIC结构体的对应的关系,分别对应physical mode和logic mode。在发送中断的时候,如果有该map表,且中断不是lowest priority和广播,则通过RTE的destination filed就可以直接找到目标VCPU,进行快速的分发。否则需要遍历所有的VCPU,逐一的和RTE的destination filed进行匹配。


本文:KVM中断系统结构关系 本文链接:https://www.21nn.cn/xitong/windows/54130.html 本站所以图片、文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如有侵权请邮件与我们联系处理。i@ki4.cn
喜欢 (0)
[1353713598@qq.com]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址