I/O虚拟化概述

1,587 阅读18分钟

关注微信公众号:Linux内核拾遗

文章来源:

1 I/O虚拟化简介

1.1 什么是I/O虚拟化

I/O虚拟化(Input/Output Virtualization)是一种设备虚拟化技术,用于将物理I/O设备抽象成多个虚拟设备,从而让多个虚拟机共享同一物理I/O设备,同时确保了每个虚拟机的隔离性和安全性,同时提升了整体系统性能。这种技术在现代数据中心、云计算和高性能计算中至关重要,因为它可以显著提高资源利用率和系统管理的灵活性。

1.2 I/O虚拟化历史背景

随着虚拟化技术的发展,CPU和内存虚拟化逐渐成熟,但I/O虚拟化的实现一直是一个挑战。I/O设备的复杂性和多样性使得直接将其虚拟化变得困难。

早期的I/O虚拟化依赖于软件模拟,当时通过完全模拟硬件的方式实现虚拟I/O操作,但性能较低。

随着虚拟化需求的增加和技术的进步,半虚拟化技术引入了改进的驱动程序(virtio),提高了效率。

近年来,硬件辅助虚拟化(如Intel VT-d和AMD-Vi)的出现显著提升了I/O虚拟化的性能,使得虚拟机能够直接访问物理设备,减少虚拟化开销,实现接近原生硬件的性能。

image-20240608010109376

2 I/O虚拟化的挑战

I/O设备虚拟化在实现过程中面临许多问题和挑战,通常而言,一个成熟的I/O虚拟化方案,它必须满足以下几个方面的基本要求。

  1. 性能

    • 低延迟和高吞吐量:性能是I/O虚拟化的关键指标,I/O操作需要尽可能接近物理硬件的性能,以确保虚拟机运行效率不受显著影响,因此虚拟化层引入的额外处理和中介步骤需要尽量减少。

    • 减少开销:I/O虚拟化过程中,虚拟机监控器(VMM)或Hypervisor对I/O操作的处理应该尽可能高效,避免增加额外的处理开销。

  2. 隔离性

    • 数据隔离:确保不同虚拟机之间的数据互不干扰,防止信息泄露或数据污染。

    • 性能隔离:避免一个虚拟机的I/O操作影响其他虚拟机的性能,保证资源公平分配。

  3. 可管理性

    • 动态资源分配:支持虚拟机的动态创建、销毁、迁移和资源调整,能够根据需求灵活配置I/O资源。

    • 设备热插拔:允许在系统运行过程中添加或移除I/O设备,提高系统维护和升级的灵活性。

  4. 兼容性

    • 多种操作系统支持:虚拟化平台需要支持多种操作系统,以便在不同的软件环境中工作。

    • 多种设备类型支持:能够兼容各种I/O设备,包括网络设备、存储设备、图形设备等,确保广泛适用性。

  5. 安全性

    • 访问控制:严格控制虚拟机对I/O设备的访问权限,防止未经授权的操作。

    • 防止设备滥用:确保虚拟机不能滥用共享的I/O设备来进行恶意操作,保护整体系统的安全性。

  6. 硬件依赖性:依赖于现代处理器的硬件虚拟化扩展(如Intel VT-d和AMD-Vi)来提升性能和简化实现,但这也意味着需要特定的硬件支持,增加了实现的复杂性。

3 I/O虚拟化原理

I/O虚拟化是一种将物理I/O设备抽象为多个虚拟设备,使得多个虚拟机能够共享这些物理设备的技术。从处理器的角度看,外设通过一组I/O资源(如端口I/O或者MMIO)来进行访问。因此,设备的虚拟化被称为I/O虚拟化。其基本思想是,虚拟机监控器(VMM)截获客户操作系统对设备的访问请求,然后通过软件模拟真实设备的效果。

一个完整的系统虚拟化方案在I/O虚拟化方面需要处理以下几个方面:

  1. 虚拟芯片组:提供虚拟的系统平台硬件,支持虚拟机操作系统的正常运行。
  2. 虚拟PCI总线布局:通过虚拟化PCI配置空间,为Guest呈现虚拟设备或直接分配使用的物理设备。虚拟PCI总线允许多个虚拟机共享同一物理PCI设备。
  3. 虚拟系统设备:包括PIC、IO-APIC、PIT和RTC等基础系统设备,这些设备被虚拟化以支持虚拟机的基本系统功能。
  4. 虚拟基本输入输出设备:包括显卡、网卡和硬盘等,这些设备是虚拟机运行所需的基本I/O设备。虚拟化这些设备使虚拟机能够进行正常的输入输出操作。

I/O虚拟化具体包含以下几个方面的虚拟化:

  1. I/O端口寄存器:VMM截获Guest对设备的I/O端口寄存器操作,并进行相应的虚拟化处理。
  2. MMIO寄存器:VMM截获Guest对设备的MMIO寄存器操作,以实现对设备的控制。
  3. 中断:中断是I/O操作中的重要机制。VMM负责截获和处理相应的虚拟设备或物理设备的中断请求,并将其转发给Guest。

image-20240608012817861

I/O设备虚拟化具体要做的工作涵盖了设备发现、访问截获、设备模拟以及设备共享等几个方面。

3.1 设备发现

设备发现是I/O虚拟化的第一步,确保Guest能够识别并使用虚拟设备。根据设备类型的不同,设备发现的方法有所差异:

3.1.1 不可枚举的设备

这些设备的资源分配是硬编码的,驱动程序通过特定方式检测设备的存在,例如读取固定端口的状态。这类设备包括:ISA设备、PS/2键盘、鼠标、RTC(实时时钟)、传统IDE控制器。

VMM在这些设备的固定端口进行模拟。它截获客户机对特定端口的访问,并模拟出设备的响应。

例如,PS/2键盘的状态可能通过读取特定I/O端口来确定,VMM需要模拟这些端口的行为以返回预期的结果。

3.1.2 可枚举的设备

这些设备的资源是软件可配置的,通常通过总线标准(如PCI)进行枚举和配置。这类设备包括PCI设备等。

VMM不仅需要模拟设备本身,还需要模拟总线的行为。

例如,PCI总线通过PCI配置空间定义一套完备的设备发现方式,并且允许系统软件通过PCI配置空间的一些字段对给定PCI设备进行资源的配置,包括允许或禁止I/O端口和MMIO,设置I/O和 MMIO的起始地址等。

3.1.3 完全虚拟的设备

这些设备没有现实中的物理对应,完全由VMM定义。例如虚拟网络接口、虚拟磁盘设备等。

VMM可以选择将这些虚拟设备挂载在现有总线(如PCI总线)上,或者定义新的虚拟总线协议。在这种情况下,Guest可能需要特定的总线驱动程序来支持这些虚拟设备。

例如,一个完全虚拟的网络设备可以作为一个PCI设备展示给客户机,Guest会通过标准的PCI配置机制发现该设备,并加载相应的驱动程序。

3.2 访问截获

虚拟设备被Guest发现后,Guest中的驱动程序会按照接口定义访问这些虚拟设备。VMM必须截获这些访问请求并进行适当的处理和模拟。根据设备是否直接分配给Guest,访问截获的处理方法有所不同。

3.2.1 非直接分配给Guest的设备

对于这些设备,VMM必须截获所有对虚拟设备的访问请求,并在VMM层进行处理和模拟。

  1. 端口I/O(Port I/O,PIO):由于I/O指令是特权指令,运行在低特权级的Guest执行I/O指令(如INOUT)访问端口时,会触发异常。MM捕获到这些异常并将其转交给设备模拟器以模拟相应的I/O操作,并将结果返回给Guest。
  2. 内存映射I/O(Memory-mapped I/O,MMIO):VMM通过将映射到虚拟设备的MMIO页表项设为无效,来截获Guest对MMIO的访问。当Guest访问无效页表项时,会触发缺页异常(page fault)。VMM捕获缺页异常,并将其转交给设备模拟器以执行相应的MMIO操作,并返回结果。
  3. 中断(Interrupts):VMM需要提供一种机制,使设备模拟器在接收到物理中断后,可以通知虚拟中断逻辑。虚拟中断逻辑模拟虚拟中断并注入到Guest中。

3.2.2 直接分配给Guest的设备

对于直接分配给客户机的设备,客户机操作系统可以直接访问这些设备的资源。

  1. 端口I/O(Port I/O,PIO):Guest可以直接执行I/O指令访问设备端口。
  2. 内存映射I/O(Memory-mapped I/O,MMIO):Guest也可以直接访问分配给它的MMIO地址。
  3. 中断(Interrupts):VMM的物理中断处理函数接收到物理中断后,辨认出中断源属于哪个Guest,并通过虚拟中断逻辑通知该Guest的虚拟中断逻辑。

3.3 设备模拟

设备模拟根据不同的虚拟化层次和技术,可以分为全虚拟化、半虚拟化,以及直接分配。

3.3.1 全虚拟化

全虚拟化是指虚拟设备与物理设备具有完全相同的接口定义,使得Guest可以使用现有的设备驱动程序来驱动虚拟设备。VMM的设备模拟器通过软件方式精确模拟物理设备的行为和接口。

基于软件的全虚拟化需要完成以下的工作:

  1. 接口模拟:VMM需要详细研究物理设备的接口定义和内部设计规范,并在软件中模拟这些接口和行为。
  2. 资源呈现:模拟器需要呈现与物理设备相同的资源,如寄存器、内存映射I/O区域等。
  3. 截获和模拟:VMM截获客户机操作系统的设备访问请求,通过模拟器执行相应的操作,并返回结果。

全虚拟化方案具有透明性和兼容性的优点,客户机操作系统无需修改驱动程序即可使用虚拟设备,并且能够支持现有的操作系统和应用程序。

但是它的缺点是性能开销大,每次设备访问都需要VMM截获并模拟,导致较大的性能开销。

当前主流的全虚拟化方案有:QEMU、VMware Workstation。

3.3.2 半虚拟化

半虚拟化是一种优化的虚拟化技术,通过提供特定的驱动程序(前端)和VMM中的模拟程序(后端)来减少上下文切换,提高性能。

半虚拟化方案需要完成以下的工作:

  1. 前端驱动:客户机操作系统中安装特定的前端驱动程序,该驱动程序知道它运行在虚拟化环境中。
  2. 后端模拟:VMM中包含对应的后端程序,负责处理前端驱动发来的请求。
  3. 通信机制:前端驱动通过高效的通信机制(如共享内存、虚拟I/O通道)直接与后端程序通信,减少上下文切换和性能开销。

半虚拟化方案的优点是高性能和灵活性,它能够减少上下文切换,提高I/O操作的效率,并且能够针对特定设备和需求进行优化。

它的缺点是Guest需要安装特定的前端驱动程序,并且前端和后端的开发和维护较为复杂。

当前主流的半虚拟化方案有:Xen、Virtio。

3.3.3 直接分配

基于硬件的直接分配是将物理设备直接分配给客户机操作系统,使其可以直接访问设备,避免了设备模拟的开销。这种方式需要硬件支持,如IOMMU(输入输出内存管理单元)和设备的多功能虚拟化支持(如SR-IOV)。

直接分配的方案需要完成以下的工作:

  1. 直接分配:VMM将物理设备直接分配给Guest,使其可以直接访问设备的寄存器和内存。
  2. 硬件支持:需要硬件支持虚拟化技术,如Intel VT-d、AMD-Vi等,通过IOMMU进行设备地址翻译和保护。

直接分配方案的优点是高性能和低开销,Guest直接访问硬件设备,无需中间层模拟,性能几乎等同于原生操作,并且减少了VMM的开销,提高系统效率。

其缺点是对硬件要求高,需要硬件支持虚拟化功能,另外它有资源分配限制,因为物理设备资源是有限的,直接分配可能导致资源紧张。

当前主流的直接分配方案有:Intel VT-d、AMD-Vi、ARM SMMU、SR-IOV(Single Root I/O Virtualization)。

3.3.4 多种虚拟化方式并存

在实际应用中,一个VMM中常常同时采用多种虚拟化方式,根据不同设备和需求选择最合适的虚拟化技术。例如:

  • 全虚拟化可以用于不支持半虚拟化驱动的旧操作系统。
  • 半虚拟化可以用于需要高性能I/O操作的现代操作系统。
  • 直接分配可以用于需要最高性能的关键设备,如GPU、网络适配器。

3.4 设备共享

在设备虚拟化中,设备共享是一个重要的概念,特别是对于需要与物理硬件交互的输入输出类设备。设备共享的实现确保了多个客户机能够同时使用同一个物理设备,而不会相互干扰。

为了实现设备共享,VMM必须提供一种机制,能够协调和管理来自多个Guest的设备访问请求,确保这些请求能够高效且正确地被处理。

3.4.1 设备模拟器和VMM的角色

在设备共享过程中,每个Guest拥有自己的设备模拟器,负责处理Guest对虚拟设备的访问请求,并将这些请求转发给VMM。VMM负责将这些请求进一步传递给物理设备,并将物理设备的响应返回给相应的设备模拟器。

3.4.2 设备请求的调度和处理

VMM需要具备处理并发请求的能力,确保多个客户机的设备访问请求能够被公平、高效地调度和处理。

  • 队列机制:VMM为每个物理设备维护一个请求队列,所有来自不同Guest的请求都被放入该队列中按序处理,以保证请求的有序性和公平性。
  • 轮询机制:VMM可以使用轮询机制,轮流处理每个Guest的请求,确保每个Guest都有机会访问物理设备。
  • 优先级机制:在某些情况下,可以根据Guest的重要性或请求的紧急程度,设置不同的优先级,以优化资源分配。

3.4.3 共享设备的具体实现

具体的设备共享实现根据设备类型的不同而有所不同,以下是一些常见设备的共享实现方法:

  1. 鼠标和键盘:VMM捕获来自物理鼠标和键盘的输入事件,然后根据当前焦点(哪一个Guest窗口处于活动状态)将输入事件分发给相应的Guest。Guest的设备模拟器将这些事件解释为虚拟设备的输入。
  2. 显卡:VMM可以通过创建虚拟GPU(vGPU)来实现显卡的共享。每个Guest拥有一个vGPU,vGPU的渲染请求被VMM收集后再统一发送给物理GPU处理。最后VMM将物理显卡的输出内容分发到各个Guest的虚拟显示器窗口中,实现多个Guest的图形显示。
  3. 硬盘:每个Guest使用一个虚拟磁盘映像文件,VMM将虚拟磁盘的读写请求转换为对物理硬盘的访问。多个Guest的磁盘请求通过VMM的调度机制进行管理。VMM可以使用缓存和写入合并策略来优化磁盘访问性能,并确保数据的一致性和安全性。
  4. 网卡:每个客户机使用一个虚拟网络接口(vNIC),VMM通过网络虚拟化技术(如桥接或NAT)将多个vNIC连接到物理网卡,并且负责调度和管理来自不同Guest的网络流量请求,确保公平带宽分配和网络流量的隔离。

4 主流I/O虚拟化模型

在I/O设备虚拟化中,Virtio、SR-IOV和VFIO是三种主要的模型,每种模型都有其独特的特点和应用场景。

4.1 Virtio

Virtio是一种半虚拟化(paravirtualized)的I/O虚拟化框架,广泛用于KVM和QEMU等虚拟化平台。它提供了一种标准接口,使虚拟机可以高效地与虚拟设备进行交互。

image-20240608111733679

Virtio框架包括以下3个关键部分:

  1. 前端驱动:运行在Guest中,负责与VMM中的后端驱动通信。

  2. 后端驱动:运行在VMM中,负责处理来自前端驱动的请求,并与物理设备进行交互。

  3. 共享内存:前后端通过共享内存进行数据交换,以减少上下文切换和I/O开销。

Virtio具备以下的优点:

  • 高效性:通过简化设备模型和I/O路径,减少虚拟化开销。
  • 兼容性:支持多种类型的虚拟设备,如Virtio-Net(网络)、Virtio-Block(块设备)等。
  • 易用性:标准化的接口使得设备驱动程序的开发和维护更加方便。

它通常应用在需要高性能和高效I/O处理的虚拟化环境,如虚拟机的网络和存储设备等。

4.2 SR-IOV

SR-IOV(Single Root I/O Virtualization)是一种硬件辅助的I/O虚拟化技术,允许一个物理I/O设备分割成多个虚拟功能(Virtual Functions,VFs),每个VF可以直接分配给不同的虚拟机。

image-20240608111354865

SR-IOV技术包含两个重要部分:

  1. 物理功能(Physical Function, PF):管理和配置SR-IOV设备的功能,由宿主机或VMM管理。
  2. 虚拟功能(Virtual Function, VF):独立的虚拟设备,直接分配给虚拟机,每个VF具有独立的I/O资源和配置空间。

SR-IOV具备以下的优点:

  • 高性能:直接将I/O请求传递给物理设备,减少虚拟化层的干预,提供接近原生硬件的性能。
  • 资源隔离:虚拟功能之间相互独立,每个虚拟机拥有独立的I/O通道,保证了隔离性和安全性。

4.3 VFIO

VFIO(Virtual Function I/O)是一种用于设备直通(Device Passthrough)的I/O虚拟化技术,允许虚拟机直接访问物理设备。VFIO利用IOMMU(Input-Output Memory Management Unit,输入输出内存管理单元)提供安全的设备访问和内存隔离。

image-20240608111544101

VFIO的底层工作原理如下:

  1. 设备绑定:物理设备被绑定到VFIO驱动程序,VFIO负责管理设备的I/O和内存访问。
  2. 直接访问:虚拟机通过VFIO直接访问物理设备,实现高性能的I/O操作。
  3. IOMMU支持:使用IOMMU提供地址翻译和保护,确保虚拟机只能访问其被分配的设备资源。

VFIO具备以下的优点:

  • 直接设备访问:允许虚拟机直接访问物理设备,I/O性能几乎与原生使用一致。
  • 安全性:通过IOMMU进行地址转换和保护,实现内存和I/O访问的隔离,确保虚拟机之间的隔离性和增强了安全性。

5 总结

I/O虚拟化是现代虚拟化技术的关键组成部分,通过将物理I/O设备抽象成虚拟设备,提升了资源利用率、性能和管理灵活性。Virtio、SR-IOV、VFIO和硬件直通是当前主流的I/O虚拟化技术,它们各有优缺点,适用于不同的应用场景。

随着虚拟化技术的不断发展,I/O虚拟化将继续演进,为数据中心、云计算和高性能计算提供更高效、更灵活的解决方案。未来,随着硬件和软件的进一步优化,I/O虚拟化的性能和可管理性将进一步提升,为更多应用场景提供支持。

关注微信公众号:Linux内核拾遗

文章来源: