arm64虚拟化-CPU虚拟化
- 1 虚拟化
- 1.1 CPU虚拟化
- 1.2 内存虚拟化
- 1.3 I/O虚拟化
- 2 异常状态
- 2.1 AArch64
- 2.2 AArch32
- 3 启动到EL2异常等级
- 4 CPU虚拟化
- 4.1 进入VM
- 4.2 退出VM
本篇博客是基于对苯叔《ARM64高级特性专题》的学习而总结的,大家如有需要可以去淘宝或者奔跑吧linux社区去购买对应的课程。
1 虚拟化
ARMv8架构引入了一系列硬件特性来支持虚拟化,例如虚拟化扩展(Virtualization Extensions,VE)、Generic Interrupt Controller version 3 (GICv3)、以及Virtualization Host Extensions (VHE)。这些特性直接在硬件层面提供了对虚拟化的支持,减少了软件模拟的负担,提高了性能。
1.1 CPU虚拟化
CPU虚拟化是基于ARMv8架构提供的硬件虚拟化扩展实现的,这些扩展为高效、安全地在同一物理处理器上运行多个虚拟机(VM)提供了基础。
1.2 内存虚拟化
内存虚拟化是虚拟化技术中的一个核心挑战,目标是让每个VM认为自己独占了整个物理内存。ARM64架构采用页表映射技术,结合二级地址转换(Translation Lookaside Buffer, TLB)和页表走遍(Page Walk)机制,实现了高效且透明的内存管理。此外,硬件支持的Address Translation Service (ATS) 和 Input Output Memory Management Unit (IOMMU) 功能加强了对I/O设备访问虚拟地址空间的控制。
1.3 I/O虚拟化
除了内存,I/O设备的虚拟化也是关键。ARM架构提供了诸如Virtual Machine Interface (VMI) 和 virtio等机制来优化设备的共享和分配。Virtio是一个半虚拟化技术,通过标准的前端/后端接口,使得来宾操作系统可以高效地与虚拟设备通信,减少了模拟开销。
2 异常状态
在虚拟化状态切换时涉及到异常的处理流程,这个时候需要了解ARMv8的异常模型。ARM64的VMM运行在EL2等级,而对应的VM则运行在低异常等级。所以进入和退出VMM需要从EL2和低异常(EL1)等级之间做切换。
The ARMv8 architecture defines two Execution States, AArch64 and AArch32. Each state is used to describe execution using 64-bit wide general-purpose registers or 32-bit wide general-purpose registers, respectively. While ARMv8 AArch32 retains the ARMv7 definitions
of privilege, in AArch64, privilege level is determined by the Exception level. Therefore, execution at ELn corresponds to privilege PLn.
ARMv8 体系结构定义了两种执行状态:AArch64 和 AArch32。每种状态分别用于描述使用 64 位宽通用寄存器或 32 位宽通用寄存器的执行情况。ARMv8 AArch32 保留了 ARMv7 中的权限定义,而在 AArch32 中则保留了 ARMv8 中的权限定义。在 AArch64 中,特权级别由异常级别决定。因此,在 ELn 执行对应于特权 PLn。
When in AArch64 state, the processor executes the A64 instruction set. When in AArch32 state, the processor can execute either the A32 (called ARM in earlier versions of the architecture) or the T32 (Thumb) instruction set.
在 AArch64 状态下,处理器执行 A64 指令集。当处于 AArch32 状态时,处理器可以执行 A32(在早期的体系结构版本中称为 ARM)或 T32(Thumb)指令集。
2.1 AArch64
2.2 AArch32
3 启动到EL2异常等级
- 实现EL2的异常向量表
- 设置EL2的异常向量表
- 创建页表(页表的恒等映射)
- 使能EL2的MMU
4 CPU虚拟化
4.1 进入VM
- 设置 HCR_EL2.RW标志位为0,表示当前要运行在AArch64环境下。
- 关闭vCPU的MMU
- 设置SPSR_EL2
- 设置ELR_EL2寄存器为VM的入口地址
- 为VM分配栈空间,将VM的栈空间栈底地址写入SP_EL1寄存器中。
- 执行ERET指令,从EL2退出进入到VM的环境,进而去执行设置到ELR_EL2寄存器中的VM入口处理函数。
4.2 退出VM
通过HVC指令可以从VM退回到VMM