2.3KVM 中设备管理
一个机器只有一套 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 将数据发往