1107 字
6 分钟
未命名 2
2025-09-10
无标签

您好,这个问题提得非常好,它正好触及了最容易混淆的地方!

实际上,KVM 并不会拦截所有的中断。 这是一个非常关键的区别。如果 KVM 需要检查系统上的每一个中断,那将会带来巨大的性能开销,并且会不必要地复杂化整个系统的设计。

KVM 知道哪些中断需要路由,不是因为它检查了每一个中断,而是因为宿主机内核(Host OS Kernel)的主中断系统已经提前帮它做好了分类和派发

我们可以把这个过程想象成一个公司的总机(Central Switchboard)


比喻:公司总机与特定部门#

  • 所有物理中断: 打入公司的所有电话。

  • 宿主机内核的主中断系统: 就是公司的总机接线员

  • 宿主机设备驱动 (如硬盘驱动): 公司的“财务部”、“销售部”等内部部门。

  • VFIO 驱动: 一个特殊的“访客专用分机”。

  • KVM: 坐在“访客专用分机”旁边等待电话的外部顾问

工作流程如下:

  1. 一个电话打进来(物理中断发生)。

  2. 总机接线员(Host 内核中断系统) 首先接起电话。

  3. 接线员看了一下电话来源,判断要找谁:

    • “哦,这个是找财务部的。” -> 电话被转接到财务部(硬盘驱动)KVM 对此一无所知。

    • “这个是找销售部的。” -> 电话被转接到销售部(宿主机网卡驱动)KVM 对此也一无所知。

    • “啊,这个电话是来自我们直通给虚拟机的那个特殊设备。” -> 接线员会将电话转接到“访客专用分机”(VFIO 驱动)

  4. 只有当电话被转接到“访客专用分机”时,坐在旁边的**外部顾问(KVM)**才会被通知到有电话来了。

KVM 不需要去监听公司所有的电话,它只需要处理总机转给它的那一小部分特定电话即可。


真实的技术流程#

  1. 中断注册 (Interrupt Registration):

    • 当宿主机系统启动时,所有物理设备的驱动程序(硬盘、网卡、USB等)都会向内核的主中断子系统注册,声明自己负责处理哪个中断号(IRQ)。

    • 当我们把一个设备直通给虚拟机时,这个设备会被绑定到 vfio-pci 驱动上。vfio-pci 驱动也会去主中断子系统注册,声明自己负责处理这个设备的中断。

    • 通过这个过程,宿主机内核已经建立了一张完整的、全局的中断路由表,明确了每个中断号应该由哪个驱动程序来处理。

  2. 中断抵达与派发 (Interrupt Arrival and Dispatch):

    • 一个物理中断(比如 IRQ 50)抵达 CPU。

    • CPU 立刻暂停当前工作,跳转到宿主机内核的通用中断处理入口(注意:不是 KVM 的代码)。

    • 这个通用的处理程序会查询那张全局中断路由表,发现 IRQ 50 的注册者是 vfio-pci 驱动。

    • 于是,内核直接调用 vfio-pci 驱动的中断处理函数。

  3. KVM 的介入:

    • vfio-pci 驱动的中断处理函数非常简单,它的核心工作就是去触发(signal)那个与 KVM 关联好的 eventfd

    • KVM 作为一个“订阅者”,一直在监听这个 eventfd。当它发现 eventfd 被触发后,它才终于知道:“那个我负责的、直通给虚拟机的设备,来中断了”。

    • 然后 KVM 再根据自己内部的、更小范围的路由表(由 KVM_IRQFD 建立),将这个事件转化为一个虚拟中断,注入给 Guest。

总结#

所以,KVM 不是一个“拦截者”,而是一个“订阅者”

它向宿主机内核的 vfio 子系统“订阅”了特定设备的中断通知。宿主机内核的主中断系统负责处理所有中断的初步派发,并将 KVM 订阅的那些中断“派送”给 vfio,最终才流转到 KVM。

这个模型非常高效,因为它避免了让 KVM 去关心那些与虚拟化无关的大量系统中断,让 KVM 可以专注于自己的核心任务。

当前时间: 2025年9月10日, 星期三, 日本标准时间下午 3:00:26。

未命名 2
https://scudays.github.io/posts/icsas/虚拟化/未命名-2/
作者
Days
发布于
2025-09-10
许可协议
CC BY-NC-SA 4.0