02 中断、事件与 VFIO 机制与实现详解
1. eventfd.c — irqfd 与 ioeventfd
依赖:CONFIG_HAVE_KVM_IRQFD(ARM64 KVM 配置中 select HAVE_KVM_EVENTFD)。
irqfd
用户态写 KVM_IRQFD 将 eventfd 与 GSI(Global System Interrupt)关联:
- 工作队列
irqfd_inject调用kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, gsi, 1, ...); - 支持 resampler(电平触发中断自动 deassert);
kvm_arch_irqfd_allowed:架构可拒绝非法组合(weak,ARM 默认可用)。
与 irqchip routing 配合:GSI → irqchip pin / MSI / ARM IRQ number。
ioeventfd
MMIO/PIO 写命中时 signal eventfd,用于 virtio 队列 kick 等高效通知,避免 VM exit 后用户态轮询。
2. irqchip.c — 中断路由
依赖:CONFIG_HAVE_KVM_IRQ_ROUTING。
核心 API:
| 函数 | 作用 |
|---|---|
kvm_irq_map_gsi |
GSI → 一条或多条 kvm_kernel_irq_routing_entry |
kvm_irq_map_chip_pin |
传统 irqchip 模型 pin → GSI |
kvm_set_irq |
向路由目标注入中断(导出给 eventfd、设备模型) |
使用 SRCU(kvm->irq_srcu)保护 kvm->irq_routing 表更新,读路径无锁并发。
ARM64:实际中断芯片为 in-kernel vGIC(arch/arm64/kvm/vgic/),irqchip.c 提供 通用路由框架,具体 set 实现在 arch。
3. vfio.c — KVM/VFIO 桥
依赖:CONFIG_KVM_VFIO(ARM64 menu 默认 select)。
目的:将 VFIO 容器/设备 fd 与 struct kvm 关联,使:
- IOMMU 组 DMA 映射与 guest 内存一致;
- coherent 与 noncoherent 设备属性传播;
- 通过
vfio_file_set_kvm(符号可选)通知 VFIO 子系统当前 VM。
1 | struct kvm_vfio { |
PowerPC 另有 CONFIG_SPAPR_TCE_IOMMU 分支;ARM64 走通用 VFIO-VFIO 路径 + irq bypass。
典型场景:RK3588 作 host 时 PCIe 网卡/GPU 直通(需 IOMMU/SMMU 支持)。
4. IRQ bypass 协同
eventfd.c 包含 <linux/irqbypass.h>;VFIO 设备作 producer,KVM 作 consumer 时,可在硬件支持下 跳过 host 内核中断处理(ARM IRQ forwarding 等)。
匹配逻辑在 04-irqbypass。
5. 数据流(MSI/irqfd → guest)
6. RK3588 注意点
- SMMU 必须正确配置,VFIO 直通才安全;
- 嵌入式 SoC 外设较少,VFIO 用例少于服务器;
- vGICv3/v4 配置见
Documentation/virt/kvm/devices/arm-vgic-v3.rst; - GIC ITS(MSI)在
vgic-its.c,与irqchip路由的 MSI 条目配合。
7. 小结
| 文件 | 层级 |
|---|---|
eventfd.c |
用户态事件 ↔ KVM 中断/MMIO 唤醒 |
irqchip.c |
GSI 路由表 |
vfio.c |
KVM ↔ VFIO DMA/IRQ 协同 |
ARM 中断 语义 在 arch/arm64/kvm/vgic/,virt/ 提供 机制与路由容器。
正在加载留言…