来源:内容由 微信公众号 半导体行业观察(ID:icbank)翻译自「embedded」,作者 Sergey Temerkhanov&Igor Pochinok,谢谢。
基于ARMv8的系统中的虚拟化工具在这些系统中起着特殊的作用,它由几个组件组成,虽然ARMv7具有特殊的CPU模式来运行虚拟机管理程序作为扩展,但在ARMv8中,它已成为架构的一部分,并且已经以名称EL2集成到特权级系统中。同时,该模式仅解决与CPU访问系统资源相关的问题,例如存储器和外围设备。为了提高虚拟化环境中设备启动的事务的效率,已经为基于ARMv8的系统开发了许多组件,例如新的中断控制器和IOMMU。本文从软件开发的角度概述了这些工具组件。
基于ARMv8的系统中的虚拟化如图1所示:EL2特权级别运行虚拟机管理程序,控制虚拟机(VM)代码的执行以及它们之间的资源共享。EL1(OS内核,特权代码)和EL0(非特权代码)的级别留给VM实例。地址转换分两个阶段执行(图2):在第一阶段,使用第一级转换表(TTBR0_EL1 / TTBR1_EL1寄存器中保存的指针)从虚拟地址计算所谓的中间物理地址(IPA); 在第二阶段,使用管理程序准备的第二级表计算实际物理地址(指针存储在VTTBR_EL2寄存器中)。这样的组织架构可以提供有效的权限分离和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:两个阶段执行的地址转换
发生此类VM退出异常的事件由HCR_EL2寄存器位定义。因此,这些可以是系统寄存器访问,包括EL1权限级别可用的访问(例如,TTBR0_ EL1 / TTBR1_EL1,FAR_EL1),缓存和TLB刷新指令,常规异常(中断,包括来自定时器和不支持的操作代码的中断),以及中断和事件等待指令。两级地址转换启用也由该寄存器控制。此外,EL2级还有一个单独的硬件定时器,它允许管理程序配置周期性中断,通常用于启动VM切换,类似于在现代操作系统中切换任务的方式。
切换过程还包括保存当前VM上下文,加载新VM以及将控制转移给它。同时,VM可以以类似于EL0级别的非特权代码执行系统调用的方式执行管理程序调用。为了执行这样的调用,VM将参数放在寄存器中并执行“hvc”指令。这导致以标准方式处理的EL2权限级别的异常。通常,这在调用标准化PSCI协议功能时发生。
还应该提到的是,管理程序可以拦截从VM到可信代码例程的调用(例如,在那里实现非虚拟化环境中的PSCI,并且在最高特权级别EL3处理对它的调用)。ARMv8架构还包含用于提高虚拟化环境性能的其他工具:除了管理程序可以分配的可共享域以减少缓存一致性流量之外,还可以为每个VM分配其自己的标识符或VMID。它的使用使得在切换VM时可以避免“昂贵的”TLB刷新。
原始版本的ARMv8提供了8位标识符,后来扩展为16位。此外,在ARMv8.1中,EL2级别的第二个转换表TTBR1_EL2作为VM主机扩展的一部分添加,因此,类型2的管理程序(它们是主机操作系统的一部分)具有更多可能性。同时,如上所述,全功能虚拟化需要VM与外围设备(网络适配器,存储控制器等)进行交互,同时最小化管理程序参与以及从设备到处理器的交付中断。
系统存储管理单元
ARMv8系统中虚拟化环境的各个方面由两个单元处理:通用中断控制器(GIC)和系统内存管理单元(SMMU)(图3)。SMMU执行I / O地址转换的方式与CPU启动的存储访问相同。该单元支持I / O地址的一级和两级转换。因此,可以在VM和管理程序中使用转换和保护内存区域的优势。因此,允许设备仅对特定存储器地址范围进行读/写。
图3:系统存储管理单元(SMMU)
此外,有时通过SMMU在I / O缓冲区上组织分散 - 收集操作很方便。转换阶段的使用模型与CPU核心的使用模型几乎相同(即,第一阶段的输出产生当前VM独有的IPA,第二阶段的输出产生整个特有的真实物理地址系统)。SMMU转换表的格式类似于CPU的格式,页面属性有一些差异。支持4,16和64 KB的页面大小以及一个或两个转换表,具体取决于寄存器设置和转换阶段,以及完整的48或52位地址空间。
每个涉及的设备都有自己的转换上下文(最终选择相关的转换表集)。可以在多个设备之间共享单个上下文。上下文选择由单元使用所谓的流ID(硬件相关的设备标识符)来执行。因此,对于PCIe设备(物理或虚拟功能),RID用作复制PCIe配置空间中的设备地址的标识符。SMMU拥有自己的TLB并支持VM ID以加速。在错误的配置检测,转换错误和其他异常的情况下,SMMU断言所谓的上下文中断(即,绑定到转换上下文的中断)。
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的系统虚拟化环境中组件与中断控制器的接口和交互
在使用ITS时,设备通过在GITS_TRANSLATOR寄存器中发出具有目标地址的写事务来发送事件信号。写入事务由正在写入的数据(包含事件ID)和源标识符(与SMMU相同)组成。系统软件对ITS寄存器进行编程,使它们指向存储器中的设备、集合和中断存储器表,这些存储器表包含处理来自指定目标CPU核心和中断ID的相关源的事件的规则。
中断导致在挂起中断表中设置元素的相应字段。对于GICv3,此机制仅针对物理中断(即,由设备直接发信号通知)进行定义。这导致管理程序实现中的某些不便。特别是,它要求管理程序执行ITS在软件中完成的所有操作。GICv4引入了以编程方式生成此类中断并将LPI转换为为相应虚拟处理器设置的虚拟中断的功能,为此引入了描述中断与目标处理器的亲和性的附加表,以及虚拟挂起中断表。如果在中断到达期间映射到目标vCPU的目标物理CPU核上正在执行具有不同标识符的VM,GICv4生成一个特殊的中断,旨在通知管理程序。为了控制虚拟中断的转换,ITS GICv4命令接口中添加了新的命令类型。
本文描述的工具为虚拟化环境的实现提供了坚实基础,现在,它们得到了各种虚拟机管理程序(第一类和第二类)的良好支持。总的来说,基于软件开发人员的请求,CPU和系统设施架构正在不断发展。
领取专属 10元无门槛券
私享最新 技术干货