2.3 KVM 中设备管理
一个机器只有一套 I/o 地址和设备。设备的管理和访问是操作系统中的突出问题、同样
也是虚拟机实现的难题, 另外还要提供虚拟设备供各个 VM 使用。在 KVM 中通过移植 Qemu
中的设备模型 (Device Model) 进行设备的管理和访问。 操作系统中, 软件使用可编程 I/O(PIO)
和内存映射 I/O(MMIO )与硬件交互。而且硬件可以发出中断请求,由操作系统处理。在
有虚拟机的情况下, 虚拟机必须要捕获并且模拟 PIO和 MMIO 的请求, 模拟虚拟硬件中断。
捕获 PIO:由硬件直接提供。 当 VM 发出 PIO指令时,导致 VM Exit 然后硬件会将 VM Exit
原因及对应的指令写入 VMCS 控制结构中,这样 KVM 就会模拟 PIO 指令。 MMIO 捕获:对
MMIO 页的访问导致缺页异常,被 KVM 捕获,通过 X86 模拟器模拟执行 MMIO 指令。 KVM
中的 I/O 虚拟化都是用户空间的 Qemu 实现的。所有 PIO和 MMIO 的访问都是被转发到 Qemu
的。 Qemu 模拟硬件设备提供给虚拟机使用。 KVM 通过异步通知机制以及 I/O 指令的模拟来
完成设备访问,这些通知包括:虚拟中断请求,信号驱动机制以及 VM 间的通信。
以虚拟机接收数据包来说明虚拟机和设备的交互。
图 3 I/O 分析
(1)当数据包到达主机的物理网卡后,调用物理网卡的驱动程序,在其中利用 Linux 内核中的
软件网桥,实现数据的转发。
(2)在软件网挢这一层,会判断数据包是发往那个设备的,同时调用网桥的发送函数,向对
应的端口发送数据包。
(3)若数据包是发往虚拟机的,则要通过 tap 设备进行转发, tap 设备由两部分组成,网络设
备和字符设备。 网络设备负责接收和发送数据包, 字符设备负责将数据包往内核空间和用户
空间进行转发。 Tap网络部分收到数据包后,将其设备文件符置位,同时向正在运行 VM 的
进程发出 I/O 可用信号,引起 VM Exit,停止 VM 运行,进入根操作状态。 KVM 根据
KVM_EXIT_REASON判断原因,模拟 I/O 指令的执行,将中断注入到 VM 的中断向量表中。
(4)返回用户模式的 Qemu 中,执行设备模型。返回到 kvm_main loop 中,执行 Kvm—main
—loop —wait ,之后进入 main_loop wait 中,在这个函数里收集对应设备的设备文件描述符
的状态,此时 tap 设备文件描述符的状态同样被集到 fd set。
(5)Kvm main—loop 不停地循环,通过 select 系统调用判断哪螋文件描述符的状态发生变化,
相应的调用对应的处理函数。 对予 tap 来说,就会通过 Qemu—send_packet 将数据发往 rtl8139