I/O 虚拟化概述
![I/O虚拟化概述](https://static001.geekbang.org/infoq/49/495a00b2694f236a59e6bf1b50ea277d.png)
关注微信公众号: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 虚拟化的性能,使得虚拟机能够直接访问物理设备,减少虚拟化开销,实现接近原生硬件的性能。
![](https://static001.geekbang.org/infoq/d6/d69c4a84b8bd80859ad0113fb2efccf5.png)
2 I/O 虚拟化的挑战
I/O 设备虚拟化在实现过程中面临许多问题和挑战,通常而言,一个成熟的 I/O 虚拟化方案,它必须满足以下几个方面的基本要求。
性能:
低延迟和高吞吐量:性能是 I/O 虚拟化的关键指标,I/O 操作需要尽可能接近物理硬件的性能,以确保虚拟机运行效率不受显著影响,因此虚拟化层引入的额外处理和中介步骤需要尽量减少。
减少开销:I/O 虚拟化过程中,虚拟机监控器(VMM)或 Hypervisor 对 I/O 操作的处理应该尽可能高效,避免增加额外的处理开销。
隔离性:
数据隔离:确保不同虚拟机之间的数据互不干扰,防止信息泄露或数据污染。
性能隔离:避免一个虚拟机的 I/O 操作影响其他虚拟机的性能,保证资源公平分配。
可管理性:
动态资源分配:支持虚拟机的动态创建、销毁、迁移和资源调整,能够根据需求灵活配置 I/O 资源。
设备热插拔:允许在系统运行过程中添加或移除 I/O 设备,提高系统维护和升级的灵活性。
兼容性:
多种操作系统支持:虚拟化平台需要支持多种操作系统,以便在不同的软件环境中工作。
多种设备类型支持:能够兼容各种 I/O 设备,包括网络设备、存储设备、图形设备等,确保广泛适用性。
安全性:
访问控制:严格控制虚拟机对 I/O 设备的访问权限,防止未经授权的操作。
防止设备滥用:确保虚拟机不能滥用共享的 I/O 设备来进行恶意操作,保护整体系统的安全性。
硬件依赖性:依赖于现代处理器的硬件虚拟化扩展(如 Intel VT-d 和 AMD-Vi)来提升性能和简化实现,但这也意味着需要特定的硬件支持,增加了实现的复杂性。
3 I/O 虚拟化原理
I/O 虚拟化是一种将物理 I/O 设备抽象为多个虚拟设备,使得多个虚拟机能够共享这些物理设备的技术。从处理器的角度看,外设通过一组 I/O 资源(如端口 I/O 或者 MMIO)来进行访问。因此,设备的虚拟化被称为 I/O 虚拟化。其基本思想是,虚拟机监控器(VMM)截获客户操作系统对设备的访问请求,然后通过软件模拟真实设备的效果。
一个完整的系统虚拟化方案在 I/O 虚拟化方面需要处理以下几个方面:
虚拟芯片组:提供虚拟的系统平台硬件,支持虚拟机操作系统的正常运行。
虚拟 PCI 总线布局:通过虚拟化 PCI 配置空间,为 Guest 呈现虚拟设备或直接分配使用的物理设备。虚拟 PCI 总线允许多个虚拟机共享同一物理 PCI 设备。
虚拟系统设备:包括 PIC、IO-APIC、PIT 和 RTC 等基础系统设备,这些设备被虚拟化以支持虚拟机的基本系统功能。
虚拟基本输入输出设备:包括显卡、网卡和硬盘等,这些设备是虚拟机运行所需的基本 I/O 设备。虚拟化这些设备使虚拟机能够进行正常的输入输出操作。
I/O 虚拟化具体包含以下几个方面的虚拟化:
I/O 端口寄存器:VMM 截获 Guest 对设备的 I/O 端口寄存器操作,并进行相应的虚拟化处理。
MMIO 寄存器:VMM 截获 Guest 对设备的 MMIO 寄存器操作,以实现对设备的控制。
中断:中断是 I/O 操作中的重要机制。VMM 负责截获和处理相应的虚拟设备或物理设备的中断请求,并将其转发给 Guest。
![](https://static001.geekbang.org/infoq/57/579c2b0c4b24484a86bf58b055af4e27.png)
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 层进行处理和模拟。
端口 I/O(Port I/O,PIO):由于 I/O 指令是特权指令,运行在低特权级的 Guest 执行 I/O 指令(如
IN
和OUT
)访问端口时,会触发异常。MM 捕获到这些异常并将其转交给设备模拟器以模拟相应的 I/O 操作,并将结果返回给 Guest。内存映射 I/O(Memory-mapped I/O,MMIO):VMM 通过将映射到虚拟设备的 MMIO 页表项设为无效,来截获 Guest 对 MMIO 的访问。当 Guest 访问无效页表项时,会触发缺页异常(page fault)。VMM 捕获缺页异常,并将其转交给设备模拟器以执行相应的 MMIO 操作,并返回结果。
中断(Interrupts):VMM 需要提供一种机制,使设备模拟器在接收到物理中断后,可以通知虚拟中断逻辑。虚拟中断逻辑模拟虚拟中断并注入到 Guest 中。
3.2.2 直接分配给 Guest 的设备
对于直接分配给客户机的设备,客户机操作系统可以直接访问这些设备的资源。
端口 I/O(Port I/O,PIO):Guest 可以直接执行 I/O 指令访问设备端口。
内存映射 I/O(Memory-mapped I/O,MMIO):Guest 也可以直接访问分配给它的 MMIO 地址。
中断(Interrupts):VMM 的物理中断处理函数接收到物理中断后,辨认出中断源属于哪个 Guest,并通过虚拟中断逻辑通知该 Guest 的虚拟中断逻辑。
3.3 设备模拟
设备模拟根据不同的虚拟化层次和技术,可以分为全虚拟化、半虚拟化,以及直接分配。
3.3.1 全虚拟化
全虚拟化是指虚拟设备与物理设备具有完全相同的接口定义,使得 Guest 可以使用现有的设备驱动程序来驱动虚拟设备。VMM 的设备模拟器通过软件方式精确模拟物理设备的行为和接口。
基于软件的全虚拟化需要完成以下的工作:
接口模拟:VMM 需要详细研究物理设备的接口定义和内部设计规范,并在软件中模拟这些接口和行为。
资源呈现:模拟器需要呈现与物理设备相同的资源,如寄存器、内存映射 I/O 区域等。
截获和模拟:VMM 截获客户机操作系统的设备访问请求,通过模拟器执行相应的操作,并返回结果。
全虚拟化方案具有透明性和兼容性的优点,客户机操作系统无需修改驱动程序即可使用虚拟设备,并且能够支持现有的操作系统和应用程序。
但是它的缺点是性能开销大,每次设备访问都需要 VMM 截获并模拟,导致较大的性能开销。
当前主流的全虚拟化方案有:QEMU、VMware Workstation。
3.3.2 半虚拟化
半虚拟化是一种优化的虚拟化技术,通过提供特定的驱动程序(前端)和 VMM 中的模拟程序(后端)来减少上下文切换,提高性能。
半虚拟化方案需要完成以下的工作:
前端驱动:客户机操作系统中安装特定的前端驱动程序,该驱动程序知道它运行在虚拟化环境中。
后端模拟:VMM 中包含对应的后端程序,负责处理前端驱动发来的请求。
通信机制:前端驱动通过高效的通信机制(如共享内存、虚拟 I/O 通道)直接与后端程序通信,减少上下文切换和性能开销。
半虚拟化方案的优点是高性能和灵活性,它能够减少上下文切换,提高 I/O 操作的效率,并且能够针对特定设备和需求进行优化。
它的缺点是 Guest 需要安装特定的前端驱动程序,并且前端和后端的开发和维护较为复杂。
当前主流的半虚拟化方案有:Xen、Virtio。
3.3.3 直接分配
基于硬件的直接分配是将物理设备直接分配给客户机操作系统,使其可以直接访问设备,避免了设备模拟的开销。这种方式需要硬件支持,如 IOMMU(输入输出内存管理单元)和设备的多功能虚拟化支持(如 SR-IOV)。
直接分配的方案需要完成以下的工作:
直接分配:VMM 将物理设备直接分配给 Guest,使其可以直接访问设备的寄存器和内存。
硬件支持:需要硬件支持虚拟化技术,如 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 共享设备的具体实现
具体的设备共享实现根据设备类型的不同而有所不同,以下是一些常见设备的共享实现方法:
鼠标和键盘:VMM 捕获来自物理鼠标和键盘的输入事件,然后根据当前焦点(哪一个 Guest 窗口处于活动状态)将输入事件分发给相应的 Guest。Guest 的设备模拟器将这些事件解释为虚拟设备的输入。
显卡:VMM 可以通过创建虚拟 GPU(vGPU)来实现显卡的共享。每个 Guest 拥有一个 vGPU,vGPU 的渲染请求被 VMM 收集后再统一发送给物理 GPU 处理。最后 VMM 将物理显卡的输出内容分发到各个 Guest 的虚拟显示器窗口中,实现多个 Guest 的图形显示。
硬盘:每个 Guest 使用一个虚拟磁盘映像文件,VMM 将虚拟磁盘的读写请求转换为对物理硬盘的访问。多个 Guest 的磁盘请求通过 VMM 的调度机制进行管理。VMM 可以使用缓存和写入合并策略来优化磁盘访问性能,并确保数据的一致性和安全性。
网卡:每个客户机使用一个虚拟网络接口(vNIC),VMM 通过网络虚拟化技术(如桥接或 NAT)将多个 vNIC 连接到物理网卡,并且负责调度和管理来自不同 Guest 的网络流量请求,确保公平带宽分配和网络流量的隔离。
4 主流 I/O 虚拟化模型
在 I/O 设备虚拟化中,Virtio、SR-IOV 和 VFIO 是三种主要的模型,每种模型都有其独特的特点和应用场景。
4.1 Virtio
Virtio 是一种半虚拟化(paravirtualized)的 I/O 虚拟化框架,广泛用于 KVM 和 QEMU 等虚拟化平台。它提供了一种标准接口,使虚拟机可以高效地与虚拟设备进行交互。
![](https://static001.geekbang.org/infoq/3d/3db51e089938b9637fa22a469a0431f8.png)
Virtio 框架包括以下 3 个关键部分:
前端驱动:运行在 Guest 中,负责与 VMM 中的后端驱动通信。
后端驱动:运行在 VMM 中,负责处理来自前端驱动的请求,并与物理设备进行交互。
共享内存:前后端通过共享内存进行数据交换,以减少上下文切换和 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 可以直接分配给不同的虚拟机。
![](https://static001.geekbang.org/infoq/45/45644a77d9059ee4053b0d3b49fa258e.png)
SR-IOV 技术包含两个重要部分:
物理功能(Physical Function, PF):管理和配置 SR-IOV 设备的功能,由宿主机或 VMM 管理。
虚拟功能(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,输入输出内存管理单元)提供安全的设备访问和内存隔离。
![](https://static001.geekbang.org/infoq/ee/ee184299845dc20a0f92c82421394a89.png)
VFIO 的底层工作原理如下:
设备绑定:物理设备被绑定到 VFIO 驱动程序,VFIO 负责管理设备的 I/O 和内存访问。
直接访问:虚拟机通过 VFIO 直接访问物理设备,实现高性能的 I/O 操作。
IOMMU 支持:使用 IOMMU 提供地址翻译和保护,确保虚拟机只能访问其被分配的设备资源。
VFIO 具备以下的优点:
直接设备访问:允许虚拟机直接访问物理设备,I/O 性能几乎与原生使用一致。
安全性:通过 IOMMU 进行地址转换和保护,实现内存和 I/O 访问的隔离,确保虚拟机之间的隔离性和增强了安全性。
5 总结
I/O 虚拟化是现代虚拟化技术的关键组成部分,通过将物理 I/O 设备抽象成虚拟设备,提升了资源利用率、性能和管理灵活性。Virtio、SR-IOV、VFIO 和硬件直通是当前主流的 I/O 虚拟化技术,它们各有优缺点,适用于不同的应用场景。
随着虚拟化技术的不断发展,I/O 虚拟化将继续演进,为数据中心、云计算和高性能计算提供更高效、更灵活的解决方案。未来,随着硬件和软件的进一步优化,I/O 虚拟化的性能和可管理性将进一步提升,为更多应用场景提供支持。
关注微信公众号:Linux 内核拾遗
文章来源:
版权声明: 本文为 InfoQ 作者【Linux内核拾遗】的原创文章。
原文链接:【http://xie.infoq.cn/article/e3da269114c0fc412cc52d74f】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论