1.1.2 I/O虚拟化

客户操作系统在启动的时候会检测硬件,以找出当前系统中连接的所有I/O设备。这些检测操作都会陷入Hypervisor中。那么Hypervisor如何处理这些设备的I/O请求呢?

通常有两种解决方案。

第一种方案:将设备的管理功能集成到Hypervisor中,作为Hypervisor的一个子系统,由Hypervisor根据这些I/O请求操作对应的I/O设备,并将结果反馈给虚拟机中的客户操作系统。这一方案的弊端在于使得Hypervisor的代码量和复杂度急剧增加,从而很难保证Hypervisor的安全性和高效率,故通常只将很少的驱动集成到Hypervisor中,比如控制台、串口驱动。

第二种方案:将所有I/O设备分配给一个虚拟机,其他虚拟机的I/O请求全部发送给这个虚拟机处理。这种方案具有极大的灵活性,可以利用现有客户操作系统中的驱动程序。如果设备本身就是一个独占设备,那么它至多被分配给一个虚拟机。但是如果设备需要在不同的虚拟机间共享,则需要额外的管理方法。在操作系统的设备驱动中,只要对该设备用互斥锁则可保证I/O操作的原子性。但是在Hypervisor的设计中使用互斥锁会破坏不同虚拟机间的隔离性。

因此I/O设备虚拟化最合适的方法就是创建相互隔离的安全虚拟机(见图1-3),让虚拟机独占该设备,并为每一个申请访问它的应用虚拟机提供服务。每个应用虚拟机通过这种模型向I/O虚拟机和人机交互虚拟机发送请求来访问真实的设备。而在虚拟设备的底层,Hypervisor需要提供必要的机制(共享内存通道)来传递这种请求,以保证虚拟机间的隔离性。

图1-3 I/O设备虚拟化模型