ARM GIC 概述:发展历史与架构演进
通用中断控制器(Generic Interrupt Controller, GIC)是 ARM 架构中管理中断的核心硬件单元,负责接收、优先级排序、分发和路由中断信号给 CPU 核心。随着 ARM 从单核向多核、从裸机向虚拟化、从移动端向服务器端演进,GIC 经历了从 GICv1 到 GICv4 的四代架构迭代。本章聚焦 GICv2/v3/v4 的主要区别与演进逻辑,帮助开发者理解不同版本的设计动机与适用场景。
GIC 发展历史
| 版本 | 发布年份 | 核心架构 | 典型应用 |
|---|---|---|---|
| GICv1 | 2008 | 单核 / 简单多核 | ARM11、Cortex-A8 早期平台 |
| GICv2 | 2011 | 多核亲和性路由 | Cortex-A9/A15、多数移动 SoC |
| GICv3 | 2013 | 可扩展多核 + 虚拟化 | Cortex-A53/A72、服务器、虚拟化场景 |
| GICv4 | 2015 | 虚拟中断直通(vLPI) | 高性能虚拟化、NVMe over Fabrics |
GICv1 奠定了中断控制器的基础模型:中断源、中断优先级、CPU 接口。GICv2 引入了对多核系统的软件亲和性路由支持,成为 ARMv7-A 时代的事实标准。GICv3 是一次重大重构,将中断路由逻辑从内存映射寄存器改为基于消息的中断(LPI),并原生支持虚拟化。GICv4 在 v3 基础上增加了虚拟中断直通能力,减少 VM 切换时的中断注入开销。
GICv2 架构特点
GICv2 是 ARMv7-A 多核平台的标准中断控制器,其架构由三个主要组件构成:
- 分发器(Distributor):全局寄存器组,管理所有中断源的使能、优先级、触发方式和目标 CPU 列表。
- CPU 接口(CPU Interface):每个 CPU 核心私有,负责向核心发送中断信号并应答中断。
- 中断类型:PPI(私有外设中断)、SPI(共享外设中断)、SGI(软件生成中断)。
GICv2 的中断路由通过 Distributor 中的 ITARGETSR 寄存器指定目标 CPU 位图,最多支持 8 个 CPU 核心。中断优先级字段为 8 位,但实际只使用高 5 位,共 32 个优先级等级。
// GICv2 中断配置示例(伪代码)
gic_distributor->ICDISER[irq / 32] |= (1 << (irq % 32)); // 使能中断
gic_distributor->ICDIPRIORITY[irq] = 0xA0; // 设置优先级
gic_distributor->ICDITARGETSR[irq] = 0x01 << cpu_id; // 路由到 CPU0
GICv3 架构演进
GICv3 针对 ARMv8-A 64 位架构重新设计,解决了 GICv2 的可扩展性和虚拟化短板。核心变化包括:
- 中断路由单元(Redistributor):每个 CPU 核心拥有独立的 Redistributor,替代全局 Distributor 的路由功能,支持大规模多核(超过 256 核)。
- LPI(Locality-specific Peripheral Interrupt):基于消息的中断类型,通过 ITS(Interrupt Translation Service)实现中断路由和转换,支持中断数量扩展至 16K+。
- 虚拟化支持:引入
GICv3 虚拟 CPU 接口(vCPU Interface),允许 Hypervisor 将物理中断直接映射为虚拟中断,减少 VM Exit 次数。 - 系统寄存器访问:CPU 接口寄存器从内存映射改为通过
ICC_*_ELn系统寄存器访问,降低访问延迟。
GICv4 核心增强:虚拟中断直通
GICv4 在 GICv3 基础上专注于虚拟化场景的性能优化,核心特性是 vLPI(Virtual LPI) 直通机制。在 GICv3 中,虚拟中断仍需要 Hypervisor 在 VM Entry/Exit 时通过写 ICH_LR* 寄存器注入中断;GICv4 允许物理设备直接向 vCPU 发送 LPI 中断,绕过 VMM 的中断注入路径。
| 特性 | GICv3 | GICv4 |
|---|---|---|
| 虚拟中断注入方式 | VMM 写 ICH_LR 寄存器注入 | 硬件直接递交给 vCPU(vLPI) |
| VM Exit 次数 | 每次虚拟中断至少 1 次 VM Exit | 0 次 VM Exit(直通场景) |
| 中断延迟(虚拟化) | 较高(受 VMM 调度影响) | 接近物理中断延迟 |
| 硬件支持 | ITS + Redistributor | ITS + Redistributor + vLPI 表 |
GICv4 引入 VLPI 配置表(VLPI Configuration Table) 和 VLPI 挂起表(VLPI Pending Table),每个 vCPU 拥有独立的虚拟中断状态表。物理设备通过 ITS 发送中断时,ITS 直接查询 vCPU 的 VLPI 表,将中断标记为挂起状态,并通过 Doorbell 机制通知 vCPU。
GICv2 / v3 / v4 关键差异总结
| 维度 | GICv2 | GICv3 | GICv4 |
|---|---|---|---|
| 最大 CPU 核心数 | 8 | 256+ | 256+ |
| 中断类型 | PPI / SPI / SGI | PPI / SPI / SGI / LPI | PPI / SPI / SGI / LPI / vLPI |
| 中断路由方式 | Distributor 位图 | Redistributor + ITS | Redistributor + ITS + vLPI 表 |
| CPU 接口访问 | 内存映射寄存器 | 系统寄存器(ICC_*_ELn) | 系统寄存器(ICC_*_ELn) |
| 虚拟化支持 | 基本物理中断直通 | 虚拟中断注入(ICH_LR) | vLPI 硬件直通 |
| 中断优先级等级 | 32 | 256 | 256 |
| 典型中断延迟(非虚拟化) | ~200ns | ~100ns | ~100ns |
| 典型中断延迟(虚拟化) | 高(无优化) | ~1-5μs | ~200-500ns |
- 裸机或简单 RTOS 系统(Cortex-A7/A9):GICv2 足够,驱动成熟且资源占用低。
- 多核 Linux 系统(Cortex-A53/A72):优先选择 GICv3,利用系统寄存器访问降低延迟,支持 LPI 减少中断线数量。
- 虚拟化场景(KVM / Xen / 裸金属虚拟化):GICv4 是首选,vLPI 直通可大幅降低虚拟中断开销。
GIC 架构演进对性能优化的启示
从 GICv2 到 GICv4 的演进反映了中断控制器设计的三个核心优化方向:
- 去中心化:从全局 Distributor 到每 CPU Redistributor,消除总线竞争和锁瓶颈,支持线性扩展。
- 减少软件介入:从 VMM 注入中断到硬件直通 vLPI,减少异常等级切换和上下文保存恢复开销。
- 中断语义丰富:从固定中断号到 LPI 消息中断,支持更多中断源和更灵活的路由策略。