前言

最近计划学习一下cpu虚拟化相关内容,其中一个重要内容就是中断虚拟化。

在学习中断虚拟化之前,首先需要对中断有基本的了解认识,虽然之前在linux内核硬中断分析中有了解,但比较片面,这里对中断会进行更深入的学习

中断硬件

本质上,内核是操作系统控制硬件的接口,其逻辑实现紧密遵循硬件规范。这种硬件强相关的特性,使得研究cpu的中断硬件机制成为理解内核中断子系统的关键点。

下面介绍一下cpu的中断硬件机制的发展

pic(Programmable Interrupt Controller)

pic,也就是8259A,其是最早的cpu的中断管理芯片,其实物图和结构图如下所示
8259A实物图
8259A结构图

中断设置

按照8259A的手册,一般通过pio的方式完成ICW(Initialization Command Words)和OCW(Operation Command Words)寄存器的读取和设置,从而完成中断触发方式、中断向量基址、中断状态等8259A工作状态的查询和设置,这里不详细介绍了,感兴趣可以查看8259A的手册

中断处理

根据8259A的手册,一个典型的中断处理流程如下所示

  1. 一个或多个IR引脚发送中断信号(触发方式由ICW1配置),对应的IRR(Interrupt Request Register)中的相关bit位锁存请求状态(直到后续被清除)
  2. PR(Priority Resolver)根据中断优先级(OCW2配置)和IMR(Interrupt Mask Register)评估所有的中断请求。如果存在有效请求,并通过INT引脚向CPU发送中断请求信号
  3. CPU检测到INT信号后,在当前指令执行完毕后发送第一个INTA脉冲(8259A手册规定的电信号)
  4. 在第一个INTA周期内,8259A会在ISR(Interrupt Service Register)中将当前IRR中最高优先级的IR对应的位进行标记,并清除IRR中相应的bit位标志
  5. 在第二个INTA周期内,8259A会通过数据总线向CPU发送8位中断类型码(ICW2配置基地址+IRQ编号)
  6. 最后,根据ICW4配置的模式结束此次中断处理(AEOI模式会自动清除ISR对应的位;否则等到CPU发送EOI命令再清除ISR对应的位)

apic(Advanced Programmable Interrupt Controller)

前面提到的pic只适用于单处理器的中断处理,而对于当前的多CPU,则需要新的中断控制器,即apic。

apic由lapic(local apic)和ioapic(I/O apic)构成,其整体结构图如下所示
apic整体结构图

整体上,lapic类似于每个CPU的8259A,用于处理其所在的CPU需要处理的中断;而ioapic则是用来负责统一接受外部设备的中断请求,并重新分配给给不同CPU的lapic

lapic

lapic的主要功能就是接受中断消息或是自身/其他lapic产生的中断,然后通知CPU处理,其整体结构图如下所示
lapic结构图

可以看到,其基本和8259A很相似,包括ISR、IRR等,但又新增了很多结构用来实现新增的功能,因此其设置和中断流程大体相似,但又有区别

中断设置

按照apic的手册,lapic的寄存器被默认被映射到起始地址为0xfee00000的连续4KB的物理内存中,可通过IA32_APIC_BASE MSR(Model Specific Register)更改基址。寄存器通过mmio方式进行读取和设置,具体的寄存器布局如下所示
lapic寄存器布局

中断处理

lapic可以处理三种中断:本地中断(诸如apic timer generated interrupts等)、IPI(Inter-Processor Interrupts)和ioapic发送的中断。lapic处理这些中断遵循下述流程

  1. 过滤中断目的地是自己的中断(本地中断目的地始终是自己,IPI和ioapic发送的中断需要根据中断的destination字段判断)
  2. 如果中断的delivery Mode是NMI(Non-Maskable Interrupt)、SMI(System Management Interrupt)、INIT、ExtINT和SIPI(Start-up IPI),则直接通过相关引脚将中断发送给CPU,完成此次中断处理
  3. 对于其他delivery Mode的中断,根据中断号将IRR对应的位进行标记(直到后续被清除)
  4. lapic基于PPR(Processor Priority Register)评估IRR中所有的中断请求。如果存在有效请求,清除IRR中相应的bit位,标记ISR中相应的bit位,并通过相关引脚将中断发送给CPU
  5. CPU在处理完中断后,向EOIR(End-Of-Interrupt Register)写入
  6. lapic清除ISR中相应的bit位,并根据SVR(Spurious Vector Register)内存可能会通过总线向所有ioapic广播EOI

ioapic

ioapic负责接收外部I/O设备的硬件中断,并将其转换成一定格式的消息,通过总线发送给一个或多个lapic,其相关示意图如下所示

ioapic引脚图
ioapic结构图

中断设置

和lapic一样,ioapic有大量用于配置/读取工作状态的寄存器。但不同的是,ioapic没有将所有的寄存器直接映射到物理内存上;其仅仅映射了两个寄存器:位于0xfec0xy00(x和y可通过APICBASE寄存器配置)的IOREGSEL(I/O Register Select),用于要访问的ioapic的寄存器编号;位于0xfec0xy10的IOWIN(I/O Window Register),用于读写选择的寄存器内容

其中最重要的是IOREDTBL(I/O Redirection Table Registers),其是一张24项的中断重定向表,每项是一个64位的寄存器,对应着ioapic的一个中断引脚的中断重定向配置信息,包含中断向量、中断的destination、中断的delivery mode等内容

中断处理

ioapic的中断处理很简单,每当其收到外部I/O设备通过中断引脚发送的中断信号后,其会根据中断引脚对应的IOREDTBL中的重定向表项格式化出一条消息,并通过总线发送给destination字段指定的lapic

msi(Message Signaled Interrupt)

在早期的计算机架构中,外设硬件中断主要通过ioapic转发至各cpu的lapic。但随着pci/pcie设备呈指数级增长,传统中断机制暴露出诸多局限性。

为此,pci规范在2.2版本引入了msi(Message Signaled Interrupt)机制,其让pci设备通过pci总线存储器写事务,将特定的消息地址(message address)和消息数据(message data)直接写入内存映射的lapic寄存器中,从而绕过ioapic直接向lapic发送中断通知,其整体的架构图如下所示(具体硬件连线细节不一定准确,主要表现绕过ioapic)

msi整体结构图

中断设置

pci的msi中断的设置是通过pci的配置空间实现的,前面博客qemu的PCI设备中简单介绍过,其配置空间如下所示
pci的配置空间

其中,msi的配置通过msi capability/msix capability实现

msi capability

msi capability的结构如下所示

msi_capability结构

可以看到,其有多个字段,但重点是Message Address(Message Upper Address)和Message Data字段

其中Message Address的结构如下所示,其定义了pci设备发出中断时内存写TLP的目的地址
Message Address结构

而Message Data则定义了写入的内容,用来描述中断的相关信息,其结构如下所示
Message Data结构

msix capability

msix capability的结构如下所示

msix_capability结构

与msi capability不同的是,其使用一个数组存放Message Address字段和Message Data字段,数组结构如下所示

msix table

中断处理

pci的中断处理遵循下述流程

  1. 当pci设备需要发起中断请求时,pci硬件会向capability中设置的Message Address地址写Message Data数据,其会以存储器写TLP的形式发送到RC(Root Complex)
  2. RC收到后,将其转换为interrupt message总线事务并广播,与ioapic操作类似

中断子系统

参考

  1. 一文了解 OS-中断
  2. 计算机中断体系一:历史和原理
  3. 计算机中断体系二:中断处理
  4. 计算机中断体系三:中断路由
  5. 8259A PIC手册
  6. Intel® 64 and IA-32 Architectures Software Developer’s Manua-Volume 3A: System Programming Guide, Part 1-CHAPTER 11 ADVANCED PROGRAMMABLE INTERRUPT CONTROLLER (APIC)
  7. 再谈中断(APIC)
  8. 82093AA I/O ADVANCED PROGRAMMABLE INTERRUPT CONTROLLER (IOAPIC
  9. PCI/PCIe 总线概述(6)—MSI和MSI-X中断机制