Armv8-A 虚拟化

本文是对Armv8-A virtualization文档的学习总结。

  • Hypervisor: 是指一个负责创建,管理和调度虚拟机(VMs)的软件
  • 虚拟化:虚拟化常常被用在云计算和企业的基础建设,通常是指在单个机器上运行多个操作系统。虚拟化能对数据中心提供令人满意的功能:
  • Isolation:隔离是虚拟化的核心,提供了一个物理机上运行的虚拟机之间的隔离。
  • High Avaliable: 虚拟化允许在物理机器之间无缝地和透明地迁移工作负载。此技术通常用于将工作负载从可能需要维护和替换的故障硬件平台上迁移出去
  • Workload balancing:负载均衡
  • SandBoxing:沙箱,为那些同机器其他部分交互的软件提供沙箱功能。

 

Standalone and hosted hypervisors

hypervisor可以被分为两种:standalone(type1)和hypervisors hosted(type2).

 type1 standalone, hypervisor直接运行在硬件上,有着硬件平台的全部控制和资源,包括CPU,物理内存。比如ARM平台的Xen。

 type2 hosted,host os拥有硬件的全部控制权,像Virtual Box和VMware这种就是type2.

全虚拟化和部分虚拟化

全虚拟化就是模拟出一个完全真实的硬件机器,但这会有严重的性能问题。部分虚拟化是只模拟出Guest os最核心的部分的虚拟平台,来代替硬件平台。今天,在包括Arm在内的大多数虚拟化硬件支持架构上,在大多数情况下,来宾操作系统运行未经修改。Guest OS认为它是在真正的硬件上运行的,除了I/O外设的驱动程序,如块存储和网络,它们使用半虚拟化的设备和设备驱动程序。这种半虚拟化I/O设备的例子是Virtio和Xen PV总线。

虚拟机和虚拟CPU

一个VM包含一个或多个vCPU

 当一个内存页分配给了一个VM,那么VM中的所有的vCPU都可以访问这个内存页。然而,一个虚拟中断的目标是一个特点vCPU,只能送到那个vCPU。

Note:严格说,应该用virtual Processing Element(vPE),而不是vCPU.请记住,处理元素(PE)是指实现Arm体系结构的机器的通用术语。本指南使用vCPU而不是vPE,因为vCPU是大多数人都熟悉的术语。但是,在体系结构规范中,使用了术语vPE。

vCPU 的定义

  • vCPU 是 Hypervisor(虚拟机监控程序)为每个虚拟机分配的虚拟处理器资源。
  • 每个 vCPU 对应物理 CPU 的一个硬件线程(如 ARMv8 的 SMP 多核架构),但通过虚拟化技术实现隔离和调度。
  • 虚拟机通过 vCPU 运行指令,其行为与物理 CPU 类似,但受 Hypervisor 的控制和约束。

 

Virtualization in AArch64
运行在EL2或更高层的软件有权访问多个虚拟化的控制组件:
• Stage 2 translation
• EL1/0 instruction and register access trapping //EL1/0指令和寄存器访问捕获
• Virtual exception generation
 

 secure state中EL2是灰色,是因为secure环境EL2不总是可以获得。

Stage 2 translation

 虚拟机只能看到哪些分配给它的资源,看不到没有分配给它的资源。

操作系统(OS)控制一组转换表,这些转换表将虚拟地址空间映射到它认为的物理地址空间。然而,这个过程会经历第二次转换,进入实际的物理地址空间,stage2 table由hyperverisor控制。stage2的翻译表的格式和stage1很类似,但是stage2中的一些属性不一样,比如Type,是Normal还是Device,被直接编码到table中,而不是MAIR_ELx寄存器。

VMIDs

每个VM虚拟机都被赋予一个虚拟机标识符VMID。VMID用来对TLB表进行标签,来标识每个目录属于哪个VM。这种标记允许同时将多个不同的vm出现在tlb中。
注意:EL2和EL3翻译机制的翻译没有用VMID标记,因为它们不受第二阶段翻译的影响。

VMID interaction with ASIDs

TLB目录也可以被标记带上一个地址空间标识符ASID。这由os完成,并且该应用程序中的所有TLB条目都用该ASID进行了标记。这意味着针对不同应用程序的TLB条目能够在TLB中共存,而不可能有一个应用程序使用属于不同应用程序的TLB条目。
每个虚拟机都有自己的ASID命名空间。例如,两个虚拟机都可能使用ASID 5,但它们用于不同的用途。ASID和VMID的组合才是重要的。
 

Emulating Memory-mapped Input/Output (MMIO)

如同在物理机器上看到的物理地址空间一样,一个VM中的IPA空间包含用来访问内存和外设的地址区域:

 虚拟机可以使用外围区域来访问实际物理外围设备,这些设备通常称为直接分配的外围设备,以及虚拟外围设备。

虚拟外围设备完全由管理程序在软件中进行仿真,如下图所示:

 

分配的外围设备是已分配给虚拟机并映射到其IPA空间中的实际物理设备。这允许在虚拟机中运行的软件直接与外围设备交互。
虚拟外设是指虚拟机管理程序(Hypervisor)将在软件中模拟的设备。相应的第二阶段表项会被标记为故障。虚拟机中的软件认为可以与外设直接通信,但每次访问都会触发第二阶段的故障,由虚拟机管理程序在异常处理程序中模拟外设的访问。
 
虚拟外设是hypervisor用软件模拟出的。当vm访问虚拟外设时,对应的stage2 table entry会被标记为fault。VM会认为直接访问了物理外设,但是每个访问都会触发stage2 fault,而hypervisor会在异常处理程序中模拟外设。
hypervisor需要知道哪个外设被访问,并且这个外设的哪个寄存器被访问,访问的类型是读还是写等等。
 
从地址开始,异常模型介绍了FAR_ELx寄存器。在处理第一阶段的故障时,这些寄存器会报告触发异常的虚拟地址。虚拟地址对管理程序来说没有实际意义,因为管理程序通常不清楚客户操作系统是如何配置其虚拟地址空间的。对于第二阶段的故障,还有一个额外的寄存器HPFAR_EL2,它报告了导致中断的地址的IPA。由于IPA空间由管理程序控制,管理程序可以利用这些信息来确定需要模拟的寄存器。
 
异常模式展示了ESR_ELx寄存器如何报告异常信息。当单个通用寄存器的加载或存储操作触发第二阶段故障时,会提供额外的综合信息。这些信息包括访问的大小和源或目标寄存器,帮助虚拟机管理程序确定对虚拟外设的访问类型。

 

System Memory Management Units (SMMUs)

一个系统中对内存的访问可能有多个来源,比如DMA controller,被某个VM分配并使用。
传统的多master MMU模型

如果os运行在虚拟机中:

 这种情况下DMA也需要一个MMU来看到跟Guest os相同的地址SMMU,sometimes also called IOMMU。

 hypervisor复制编码这个SMMU,这样DMA能看到和虚拟机一样的内存视角。

 Trapping和指令模拟

有时候虚拟会需要访问一些低层次的处理器控制,但是你并不想VM去直接控制这些寄存器。这时候就用到trap技术。当VM有一个特殊操作时,比如读一个特殊寄存器,这时会引发一个异常,然后陷入hypervisor。hypervisor再根据VM的操作去执行其他的操作或配置。

 表示寄存器的虚拟值:

例如,ID_AA64MMFR0_EL1报告支持处理器中与内存系统相关的特性。操作系统可能会将此寄存器视为启动的一部分,以确定内核中要启用哪些功能。管理程序可能希望向客户操作系统呈现一个不同的值,称为虚拟值。为此,管理程序会触发覆盖读取该寄存器的陷阱。在陷阱异常时,管理程序会确定触发了哪个陷阱,然后模拟操作。在这个例子中,管理程序用虚拟值ID_AA64MMFR0_EL1填充目标寄存器,如下所示:

 

MIDR&MPIDR

频繁的陷入hypervisor会带来额外的性能开销,对于不常用的寄存器访问可以陷入hypervisor,如果是经常需要访问的,但hypervisor又需要修改值怎么办呢?虚拟值!

管理程序可能希望Guest操作系统查看这些寄存器的虚拟值,而不必捕获每个单独的访问。对于这些寄存器,该体系结构提供了一种替代捕获的替代方案:

• VPIDR_EL2.这是对MIDR_EL1的EL1读取所要返回的值。

• VMPIDR_EL2.这是对MPIDR_EL1的EL1读取所要返回的值。

系统管理程序可以在进入虚拟机之前设置这些寄存器。如果在虚拟机中运行的软件读取MIDR_EL1或MPIDR_EL1,硬件将自动返回虚拟值,而不需要设置陷阱。

 

虚拟中断(异常)

虚拟系统下有两种中断需要处理,一种是中断送到hypervisor,另一种是送到VM,特别要考虑有些送到VM的中断,而VM此时并没有运行.

为了启用这些机制,该体系结构包括对虚拟中断的支持:virq、vFIQs和vSErrors。这些虚拟中断的行为与它们的物理对应物(IRQs、FIQs和SErrors)类似,但只能在EL0和EL1中执行时发出信号。在EL2或EL3中执行时,不可能接收到虚拟中断。

为了向EL0/1发送虚拟中断,管理程序必须在HCR_EL2中设置相应的路由位。例如,要启用vIRQ信号,管理程序必须设置HCR_EL2。据我所知,这一设置会将物理IRQ异常路由到EL2,并使虚拟异常能够被EL1接收。虚拟中断按类型控制。理论上,虚拟机可以配置为接收物理FIQ和虚拟IRQ。实际上,这种情况较为罕见。通常情况下,虚拟机仅配置为接收虚拟中断。

有两种机制来生成虚拟中断:

由核心内部,使用HCR_EL2中的控件。

•使用GICv2或更高版本的中断控制器。

对于第二种方式:

这两个接口是相同的,除了一个表示物理中断,另一个表示虚拟中断。该虚拟机管理程序可以将虚拟CPU接口映射到一个虚拟机中,从而允许该虚拟机中的软件直接与GIC进行通信。这种方法的优点是,系统管理程序只需要设置虚拟接口,而不需要模拟它。这种方法减少了执行需要被捕获到EL2上的次数,从而减少了虚拟化中断的开销。注意:虽然Arm GICv2可以与Armv8-A设计一起使用,但更常见的是使用GICv3或GICv4。

实际可以理解为arm GIC有两个中断发出源,分别是物理中断和虚拟中断,这两个中断本质都是物理中断,只不过虚拟中断是由物理中断转发出来(forwarding).

到目前为止,我们已经了解了如何启用和生成虚拟中断。让我们来看一个示例,该示例显示将虚拟中断转发给vCPU的过程。在本示例中,我们将考虑分配给VM的物理外设,如下图所示:

该图说明了这些步骤:

1。物理外围设备声称其中断信号进入GIC。

2.GIC生成一个物理中断异常,IRQ或FIQ,它通过HCR_EL2的配置路由到EL2。IMO/FMO.管理程序识别外围设备,并确定它已被分配给虚拟机。它检查中断应该被转发到哪个vCPU。

3.系统监控程序将GIC配置为将物理中断作为虚拟中断转发到vCPU。然后,GIC将断言vIRQ或vFIQ信号,但处理器将在EL2中执行时忽略该信号。

4.系统管理程序将控制权返回给vCPU。

5.现在处理器在vCPU(EL0或EL1)中,就可以使用来自GIC的虚拟中断了。此虚拟中断将受到PSTATE异常掩码的影响

 

Virtualizing the Generic Timers

Arm架构中包含了一个通用定时器,这是每个处理器都配备的一套标准化定时器。通用定时器由多个比较器组成,这些比较器与一个共同的系统计数进行对比。当比较器的值等于或小于系统计数时,它会触发中断。下图展示了系统中的通用定时器(橙色部分)及其组成部分:比较器和计数模块。

 在虚拟化系统中,两个vCPU的调度情况可能如下图:

 你是否想过,当过了4ms之后,每个vCPU经历的时间是多少?或者您希望在虚拟时间2ms之后中断,这是vCPU所经历的时间,还是在墙钟时间2ms之后中断?

Arm结构对这两种能力都可以提供。运行在vCPU上的软件可以获得两个timer

  • EL1物理 Timer
  • EL1虚拟 Timer

EL1物理计时器与系统计数模块生成的计数进行比较,使用此计时器可以获取实际时间

EL1虚拟计时器则与一个虚拟计数进行比较,这个虚拟计数是物理计数减去一个偏移量。虚拟机管理程序会在寄存器中指定当前调度的vCPU的偏移量,这样可以在vCPU未被调度运行时隐藏时间的流逝。

posted @ 2025-03-31 17:44  老胡同学  阅读(126)  评论(0)    收藏  举报