虚拟化中的中断机制:X86与PIC 8259A探索(上)

本系列深入探讨虚拟化中断技术,从X86架构和PIC 8259A的基础,到IOAPIC和MSI的编程,再到MSIX技术与Broiler设备的实战应用,全面剖析中断虚拟化的前沿进展。

X86 中断机制

在计算机架构中,CPU 运行的速度远远大于外设运行的速度,在早期程序设计时,计算机如果要获得外部设备完成 IO 情况,计算机就不得不通过轮询来查询外设完成情况,因此往往做了很多无用的外设,从而导致计算机性能低下。为了解决这个问题引入了中断机制,中断 是为了解决外部设备完成某些工作之后通知 CPU 的一种机制,中断大大解放了 CPU, IO 操作效率大增. 在 X86 架构中,中断是一种电信号,由硬件外设产生,并直接送入中断控制器的输入引脚,然后由中断控制器下处理器发送相应的信号。处理器一旦检查到该信号,便会中断当前处理的工作转而处理中断。

X86 架构的 CPU 为中断提供了两条外接引脚: NMI 和 INTR. 其中 NMI 是不可屏蔽中断,通常用于电源掉电和物理存储器奇偶校验; INTR 是可屏蔽中断,可以通过设置中断屏蔽位来进行中断屏蔽,主要用于接受外部硬件的中断信号,这些信号由中断控制器传递给 CPU。常见的中断控制器有两种: 8259A PIC 和 APIC.

PIC 8259A

X86 架构中,传统的 PIC(Programmable Interrupt Controller) 可编程中断控制器由两片 8259A 外部芯片以级联的方式连接在一起,每个芯片可处理多达 8 个不同的 IRQ,Slave PIC 的 INT 输出线连接到 Master PIC 的 IRQ2 引脚,所以可用的 IRQ 线的个数达到 15 个. 中断引脚具有优先级,其中 IR0 优先级最高,IR7 优先级最低。PIC 内部具有三个重要的寄存器:

IRR(Interrupt Request Register) 中断请求寄存器, 一共 8 bit 对应 IR0 ~ IR7 8 个中断引脚. 某位置位代表收到对应引脚收到中断但还没有提交给 CPU. ISR(In Service Register) 服务中寄存器,一共 8 bit,某位置位代表对应引脚的中断已提交给 CPU 处理,但 CPU 还没有处理完. IMR(Interrupt Mask Register) 中断屏蔽寄存器,一个 8 bit,某位置位代表对应的引脚被屏蔽. 除此之外,PIC 还有一个 EOI 位,当 CPU 处理完一个中断时,通过写该 bit 告知 PIC 中断处理完毕。PIC 向 CPU 递交中断的流程如下:

1. 一个或多个 IR 引脚产生电平信号,若中断对应的 IRR bit 没有置位.

2. PIC 拉高 INT 引脚通知 CPU 中断发生

3. CPU 通过 INTA 引脚应答 PIC 表示中断请求收到

4. PIC 收到 INTA 应答之后,将 IRR 中具有高优先级的位清零,并置位 ISR 对应位

5. CPU 通过 INTA 引脚第二次发出脉冲,PIC 将最高优先级 Vector 送到数据线上.

6. 等待 CPU 写 EOI.

7. 收到 EIO 后,ISR 中最高优先级位清零.


APIC: Local APIC and I/O APIC

PIC 可以在 UP(单处理器)平台上工作,但无法用于 MP(多处理)平台,为此 APIC(Advanced Programmable Interrupt Controller) 应运而生。APIC 由位于 CPU 中的本地高级可编程中断控制器 LAPIC(Local Advanced Programmable Interrupt Controller) 和位于主板南桥中 I/O 高级可编程中断控制器 I/O APIC(I/O Advanced Programmable Interrupt Controller) 两部分构成,他们的关系如上图.

每个 Logical Processor 逻辑处理器都有自己的 Local APIC,每个 local APIC 包含了一组 Local APIC 寄存器,用于控制 kicak 和 external 中断的产生、发送和接受等,也用于产生和发送 IPI。Local APIC 寄存器组以 MMIO 形式映射到系统的存储域空间,因此可以像操作物理内存一样访问。Local APIC 寄存器在存储域的起始物理地址为 0xFEE0000; 在 x2APIC 模式的 Local APIC 寄存器映射到 MSR 寄存器组来代替,因此可以使用 RDMSR 和 WRMSR 指令来访问 Local APIC 寄存器。

Local APIC 由一组 LVT(Local vector table) 寄存器用来产生和接口 Local interrupt source. 由 LVT 的 LINT0 和 LINT1 寄存器对应着处理器 LINT0 和 LINT1 Pin, 它们可以直接接受外部 I/O 设备或连接 8259A 兼容类的外部中断控制器. 典型的 LINT0 作为处理器的 INTR Pin 接着外部的 8259 类的中断控制器的 INTR 输出端,LINT1 作为处理器的 NMI Pin 接外部设备的 NMI 请求.

IO APIC 通常有 24 个不具有优先级的引脚用于连接外部设备,当收到某个引脚的中断信号之后,IO APIC 根据软件设定的 PRT(Programmable Redirection Table) 表查找对应引脚的 RTE(Redirection Table Entry). 通过 PTE 的各个字段,格式化出一条包含该中断所有信息的中断信息,再由系统总线发送给特定的 CPU 的 Local APIC,Local APIC 收到该信息之后择机将中断递交给 CPU 处理. IO APIC 也有自己的寄存器,同样也是通过 MMIO 映射到存储域空间。在 APIC 系统中,中断发起大致流程如下:

1. IO APIC 收到某个引脚产生的中断信号

2. 查找 PRT 表获得引脚对应的 RTE

3. 根据 RTE 个字段格式化出一条中断信息,并确定发送给哪个 CPU 的 LAPIC

4. 通过系统总线发送中断信息

5. Local APIC 收到中断信息,判断是否由自己接受

6. Local APIC 确认接受,将 IRR 中对应的位置位,同时确认是否由 CPU 处理

7. 确认由 CPU 处理中断,从 IRR 中获得最高优先级中断,将 ISR 中对应的位置位,提交中断。对于边缘触发的中断,IRR 中对应的位此时清零.

8. CPU 处理完中断,软件写 EOI 寄存器告知中断处理完成. 对于电平触发中断,IRR 中对应的位清零. Local APIC 提交下一个中断.

在 MP(多处理器) 平台上,多个 CPU 要协同工作,处理器间中断 (Inter-processor Interrupt, IPI) 提供 CPU 之间相互通信的手段。CPU 可以通过 Local APIC 的 ICR(Interrupt Command Register, 中断命令寄存器) 向指定的一个/多个 CPU 发送中断. OS 通常使用 IPI 来完成诸如进程转移、中断平衡和 TLB 刷新等任务.

中断重要概念

中断可分为同步中断(Synchronous Interrupt) 和异步中断(Asynchronous Interrupt)。同步中断是当指令执行时由 CPU 控制单元产生,之所以称为同步,是因为只有在一条指令执行完毕后 CPU 才会发出中断,发生中断之后 CPU 立即处理,而不是发生在代码指令执行期间,比如系统调用; 异步中断是指由其他硬件设备依照 CPU 时钟信号随机产生,即意味着中断能够在指令之间发生,中断产生之后不能立即被 CPU 执行.

在 Intel X86 架构中,同步中断称为异常(exception), 异步中断称为中断(Interrupt), 中断可以分为可屏蔽中断(Maskable Interrupt) 和不可屏蔽中断(Nomaskable Interrupt). 异常可分为: 故障(Fault)、陷阱(Trap)和终止(abort)三类. 在 X86 架

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值