基于ARMv8系统中的虚拟化工具在这些系统中起着特殊作用,它由几个组件组成。虽然ARMv7具有作为扩展的特殊CPU模式来运作虚拟机管理器(hypervisor),但在ARMv8中,已成为架构的一部分,并命名为EL2,整合到特权级(privilege-level)系统中,同时,该模式仅解决与CPU访问系统资源(例如内存和周边)相关的问题。为提高虚拟化环境中设备启动事务(transaction)的效率,已经为基于ARMv8的系统开发了许多组件,例如新的中断控制器和IO内存管理单元(MMU)。本文将从系统软件开发的角度介绍这些工具组件。
基于ARMv8的系统中的虚拟化如图1所示。EL2特权级运作虚拟机管理器,控制虚拟机(VM)程序代码的执行,以及它们之间的资源共享;EL1(OS核心、特权程序代码)和EL0(非特权程序代码)级留给VM实例。地址转换分两个阶段执行(图2),在第一阶段,使用第一级转换表(TTBR0_EL1/TTBR1_EL1寄存器中保存的指针)从虚拟地址计算所谓的中间物理地址(IPA);在第二阶段,使用管理器准备的第二级表计算实际物理地址(指针储存在VTTBR_EL2寄存器中)。这样的组织架构可以提供有效的权限分离和VM与硬件的隔离,例如,它允许拥有具有一个相同VM的许多实例。
图1 基于ARMv8系统中的虚拟化。(数据源:Auriga)
两级转换
两级转换允许VM维护自己的转换表,同时还允许管理器完全控制最终结果。EL2特权级专门用于执行管理器程序代码,与其他级别有一些差异,因此,它是最小特权级别,其中,可访问特殊寄存器VTTBR_EL2、VTCR_EL2,以及用于VM管理的一些其他寄存器。
在ARMv8架构的原始版本中,仅为管理器提供了一个转换表,而为当前VM提供了另一个转换表。管理器可以访问多个特殊寄存器,透过这些寄存器可以设置在EL1级VM可见的配置参数,例如CPU标识符(制造商、版本等)和多处理器系统ID。这允许操作者将在同一系统上运作的VM呈现给来自不同版本和制造商不同拓扑的虚拟SMP系统及CPU。
如果在VM中发生需要管理器干预的事件,则其处理按如下流程执行:
●EL2级发生异常。
●根据其类型,从表中调用相应的处理程序(地址储存在VBAR_EL2寄存器中)。
●执行必要的行动。
●如果需要,将所需值放入寄存器。
●管理器返回到退出发生处的VM(如果相应地设计了管理器,则切换到另一个VM)。
图2 分两个阶段执行的地址转换。(数据源:Auriga)
发生此类VM退出异常的事件由HCR_EL2寄存器定义。因此,这些可以是系统寄存器访问,包括EL1特权级可用的访问(例如,TTBR0_EL1/TTBR1_EL1、FAR_EL1)、高速缓存和TLB刷新指令、常规异常(中断、包括来自定时器和不支持的操作程序代码的中断),以及中断和事件等待指令,且两级地址转换的启能也由该寄存器控制。此外,EL2级还有一个允许管理器配置周期性中断的单独硬件定时器,中断通常用于启动VM切换,与现代OS中切换任务的方式类似。
切换过程还包括保存当前VM背景(context)、加载新VM,以及将控制转移给它,同时,VM可以以类似于EL0级的非特权程序代码执行系统调用的方式来执行管理器调用。为执行这种调用,VM将参数放在寄存器中并执行“hvc”指令。这导致以标准方式处理的EL2特权级的异常,通常,这发生在调用标准化PSCI协议功能时。
不仅如此,管理器可以拦截从VM到可信任程序代码例程的调用(例如,在那里实现非虚拟化环境中的PSCI,并且在最高特权级EL3处理对它的调用)。ARMv8架构还包含用于提高虚拟化环境性能的其他工具,除了管理器为减少高速缓存一致性流量问题分配的可共享域之外,还可为每个VM分配其自己的标识符或VMID。它的使用使得在切换VM时可避免“昂贵的”TLB刷新。
原始版本的ARMv8提供8位标识符,后来扩展为16位。此外,在ARMv8.1中,EL2级的第二个转换表TTBR1_EL2作为VM主机扩展的一部分添加,因此Type 2的管理器(它们是主机OS的一部分)具有更多可能性。同时,如上所述,全功能虚拟化需要VM与周边(网络适配器、储存控制器等)进行互动,同时最小化管理器的参与,以及从周边到处理器的交付中断实施。
系统内存管理单元
ARMv8系统中虚拟化环境的这些方面由两个单元处理:通用中断控制器(GIC)以及,系统内存管理单元(SMMU)(图3)。SMMU执行I/O地址转换的方式与CPU启动的内存访问相同,该单元支持I/O地址的一级和两级转换,可以在VM和管理器中利用转换和保护内存区域的好处,因此,允许设备仅对特定内存地址范围进行读/写。
图3 系统内存管理单元。(数据源:Auriga)
此外,有时透过SMMU在I/O缓冲区上组织分散-收集(scatter-gather)操作会很方便。转换阶段的使用模型与CPU核心的使用模型几乎相同(即第一阶段的输出产生当前VM独有的IPA;第二阶段的输出产生整个系统唯一的真实物理地址)。SMMU转换表的格式类似于CPU所用的格式,但页面属性有差异,取决于寄存器设置、转换阶段,以及完整的48或52位地址空间,可支持4、16和64KB页面大小,以及一或两个转换表。
每个涉及的设备都有自己的转换背景(它最终选择相关的转换表集)。可在多个设备之间共享单一背景,背景选择由单元使用所谓的流ID(硬件相关的设备标识符)来执行,因此,对于PCIe设备(物理或虚拟功能),RID用于复制PCIe配置空间中的设备地址标识符。SMMU拥有自己的TLB并支持VM ID以实现加速,在检测到错误配置、转换错误和其他异常情况下,SMMU断言(assert)所谓的背景中断(即绑定到转换背景的中断)。
SMMU的维护类似于CPU MMU的维护。但处理器MMU上的操作(TLB复位、转换结果检索等)是利用特殊指令执行;而对于SMMU,它们是透过访问背景寄存器执行。截至2017年底,有多个版本的SMMU规范,最新版本为3.1。SMMU版本3.0和3.1支持扩展流ID,并使用RAM中的表来匹配流和背景ID,这样的表可以有一或两个级别。表内元素包含:指向也储存在内存中的背景描述符指针、与元素相关的VM标识符,以及指向第二级转换表的指标。
反过来,背景描述符包含指向第一级转换表的指标。SMMUv3的一个重要特性是能够在软件响应之前停止执行事务,这种模型允许设备访问不在RAM中的页面(例如,交换文件/交换分区)或者推测性地进行指配。SMMU还可以自动设置转换表中的更改(或脏的)页面指示位,这可以简化VM迁移、VM状态快照等。SMMUv3还支持VM标识符屏蔽,允许在不同VM之间共享转换表,从而降低TLB压力。
在SMMUv3中,控制和事件讯令都已经过有效的重构:该单元使用事件队列,它是内存中的环形缓冲区;背景中断被替换为表示队列中出现新描述符的中断。其中,有一个单独队列,即所谓的页面请求接口(PRI),可用于获取设备访问的页面。如上所述,使用内存中的控制块,而非背景寄存器,并透过将命令描述符写入命令队列并提交它们以实现背景管理。
GIC在虚拟化环境功能中发挥着至关重要的作用。到2017年底,该规范的第四版是最新版,而第二版是用于ARMv8处理器的最小版本。GIC本身是个非常复杂的设备,因为需要在多处理器系统中提供中断(现有实现可以有256或更多的硬件线程),但是,本文仅考虑与虚拟化直接相关的控制器功能。大多数GIC寄存器都没有虚拟化,这会在访问时导致VM退出。同时,该规范引入了诸如虚拟中断之类的概念。
中断虚拟化
虚拟中断可分为两个虚拟组中的一个:组0和组1。组0保存所谓的快速中断请求(FIQ),而组1保存所有其他中断请求(IRQ),处理器以与处理物理中断完全相同的方式处理虚拟中断。基于ARMv8的虚拟化环境中的中断处理组织,如来自设备的物理中断被发送到EL2级(到虚拟管理器),且如果该中断针对某一事件,则管理器启动虚拟处理器上的相应虚拟中断,系统和服务中断都可以路由到虚拟机管理器。根据GIC规范,虚拟机管理器在虚拟化之前处理物理中断。
GIC中的中断虚拟化支持由表示虚拟中断的事件清单为依托,它们储存在相应寄存器中并作为虚拟IRQ或FIQ处理。透过处理器寄存器接口的虚拟中断控制类似于物理中断控制,因此,在虚拟处理器上运作的软件能够执行以下操作:
●设置虚拟优先级屏蔽。
●控制在组内解释虚拟优先级的方式。
●确认虚拟中断。
●降低虚拟中断优先级。
●停用虚拟中断。
为管理虚拟中断,CPU接口提供了一组系统寄存器,其地址与物理中断控制寄存器的地址相同,这意味着控制机制对于VM是绝对透明。虚拟中断列表上的寄存器数量是由实现决定,但限制为16。如果寻址到的虚拟处理器的中断数超过可用寄存器数,则管理器可将相应事件存入内存,待有空闲寄存器时再将其写入,而中断优先级由硬件处理。
虚拟接口产生寻址到管理器的中断,该中断宣示管理器应做出相应响应的事件(空的中断列表、启用和禁用组、发讯令通知不在寄存器中的中断有中断结束事件等)的到来。除专用周边中断(PPI)和共享周边中断(SPI)之外,ARMv8系统还有一整类称为特定于位置的周边中断(LPI)的消息(消息讯令的中断;MSI)启发的中断信号。
GICv3及更高版本的GIC扩展了对此类中断的支持,可根据特殊规则(中断转换服务;ITS)处理中断消息。但是,这些功能与虚拟化有某种间接关系,但值得简要描述它们以提供GICv4中引入变更的一般视图。
图4 基于ARMv8系统虚拟化环境中组件与中断控制器的接口和互动。(数据源:Auriga)
在使用ITS时,设备透过向目标地址储存在GITS_TRANSLATOR寄存器中的单元发出写入事务来发送事件信号。事务写入由正在写入的数据(包含事件ID)和源标识符(与SMMU相同)组成。系统软件对ITS寄存器进行程序设计,使它们指向设备、集合和内存中的中断内存表,这些内存表包含处理来自指定目标CPU核心和中断ID相关源的事件规则。
中断导致在挂起中断表中设置元素的相应字段。对于GICv3,该机制仅针对物理中断(即由设备直接发讯令通知)进行定义,这导致管理器实现中的某些不便,特别是它要求管理器执行ITS在软件中完成的所有操作。GICv4导入了以程序设计方式生成此类中断,并将LPI转换成为相应虚拟处理器设置的虚拟中断能力,为此引入了描述中断与目标处理器亲和性(affinity)的附加表,以及虚拟挂起中断表。如果中断到达时,映像到目标虚拟CPU的目标物理CPU核心正在执行具有不同标识符的VM,则GICv4会生成一个旨在通知管理器这种情况的特殊中断。为了控制虚拟中断的转换,ITS GICv4命令接口中添加了新的命令类型。
本文中描述的工具代表了虚拟化环境实现的坚实基础,现在它们得到各种虚拟机管理器(第一类和第二类)的良好支持。总的来说,因应软件开发人员的请求,CPU和系统设施架构正在不断发展之中。
编按:本文作者Sergey Temerkhanov,Auriga首席软件工程师;Igor Pochinok,莫斯科罗蒙诺索夫国立大学研究运算中心(MSU RCC)移动和嵌入式软件系统实验室负责人
关注最前沿的电子设计资讯,请关注“电子工程专辑微信公众号”