[A-20][V-07]ARMv8/v9-内存虚拟化(Stage-2 Translation)

文摘   2024-11-30 19:07   辽宁  
ver0.2

前言

前一篇文章我们和大家探讨内存虚拟化的原理,很多小伙伴私信我666的、还有没看懂的,....其实都很正常,主要是怪作者水平一般没说明白。写这些文章的初衷就是和大家分享交流,也是抛砖引玉,希望更多的伙伴能够加入研究虚拟化技术的群体中来。还有我们这是非主流社区,不适应的,我劝你留下来慢慢适应,哈哈哈哈。我们这个系列的文章写得线条都比较粗,一方面是限于篇幅,另外一方面是限于作者精力有限,还有最重要的一方面就是笔者认为,要深入一个基础体系首先还是要建立宏观的框架,然后再深入到这个框架的某个面或者线深入下去,这样的效率比较高。比如虚拟化的核心Hypervisor: [V-01] 虚拟化概论-Hypervisor(基于AArch64)。你要研究虚拟化技术,起码对这个核心要有一些最起码的感觉才可以。另外由于虚拟化技术和体系的深度耦合性,比如ARM、x86、RISC-V,这就需要你得花一些精力研究系统架构,而作为系统架构的核心Master-CPU[V-02] 虚拟化基础-CPU架构(基于AArch64)更是需要优先了解,并建立起起码的感觉。也许你可能会说,为啥是"感觉",哈哈哈,别问,问就是当年一个大神和我说的。后来历尽沧桑之后,发现神说的是对的,就和谈恋爱一样,就是反反复复拉扯,时间长了有感觉了,才能继续下去。说到这里想到了给公司的新员工培训,300多人巴巴的讲了两天,讲得Linux、QNX、神经网络技术一点没记住,扯得犊子,怎么谈恋爱,怎么辨别人家是否真心喜欢你还是把你当备胎, 怎么判断明星会不会塌方.....记得死死地。2、3年之后在在公司看见我,张嘴就是老师你讲得全对(吴某凡确实塌了),此情此景,我一般都会说,别叫我老师,我不配,哈哈哈哈。再扯回来,我们今天会针对大家的一些疑问结合ARM体系对内存的虚拟化再深入一下,对一些细节再写得清晰一些,希望能帮助大家加深对内存虚拟化的理解。

正文

1.1  Stage-2 Translation Overview

前一篇文章中,我们讲述了ARM体系下实现内存虚拟化的核心技术点,就是在MMU和ARM异常处理机制的配合下完成的虚拟地址空间到物理地址空间的转换,让软件上下文获得了运行的必要物理内存空间的资源。还是老规矩,看图说话。如图1-1所示,这是一个典型的基于ARM架构的两级地址翻译模型。

图1-1 ARM两级地址翻译模型

先对这个模型做一个简要的分析:

(1) 首先理解的就是虚拟机VM,因为VM是连接GustOS和Hypervisor的纽带。而VM是工作在IPA 空间,那么就要先对IPA空间有一个充分的认识。

(2) 我们可以看到IPA空间到PA的空间也需要映射,这个映射的过程同样需要记录,一块物理内存空间分配给了VM1,就不能再分配给VM2了,那么Hypervisor同样需要一个账本对这些空间分配的行为做记录,而对这个Stage-2阶段的账本,我们同样需要搞清楚。

(3) 两本帐就是两个页表,VA到IPA再到PA,需要关联两个页表,而页表项中记录着这个VA空间和IPA空间的属性。这两边的属性一致的时候还好,不一致的时候ARM又是怎么处理的,这个方面也需要搞清楚。

在展开具体讨论之前我们还是结合手册看一下Stage-2 Translation的官方定义:

Stage 2 translation allows a hypervisor to control a view of memory in a Virtual Machine (VM). Specifically, it allows the hypervisor to control which memory-mapped system resources a VM can access, and where those resources appear in the address space of the VM.

This ability to control memory access is important for isolation and sandboxing. Stage 2 translation can be used to ensure that a VM can only see the resources that are allocated to it, and not the resources that are allocated to other VMs or the hypervisor.

For memory address translation, stage 2 translation is a second stage of translation.

可以看出手册中给出的官方定义,stage 2 translation就是一种ARM搞出来的给Hypervisor重新分配资源的机制。

1.2 IPA空间

1.2.1 IPS的概念

虚拟机VM是连接GuestOS和真是物理机的一个纽带,根据虚拟化的思想,VM代表着分配给一个GuestOS的全部资源的集合。这些资源可以是这个GuestOS独占的,也可以是和其他的GuestOS共享,这就要看具体的系统资源的配置。独占的情况:我们可以把Modem IP分配给一个运行TBox 的GuestOS独占,而把Wifi和BT IP分配给运行IVI系统的Android(Guest OS)独占。共享的情况:比如以太网资源、ADsp资源一般会配置为各个GuestOS共享,虽然他们也可以配置为某个GuestOS独占。这里我们放一张工程中常用的架构图,大家可以自己体会一下,如图1-2所示。

图1-2 一种典型的虚拟化资源分配方式

这里面有一个基础资源就必须配置为各个GuestOS共享,那就是物理内存空间。道理很简单,一般情况下不可能有GuestOS会脱离开物理内存和设备还能工作。因此,分配给一个VM下的资源在ARM的体系下也要介绍内存模型的抽象管理,但是他和真是的物理内存空间又所区别,这块特殊的区域在ARM的江湖中被称为IPA Space 或者 IPS。

1.2.2 IPA 空间的映射

搞清楚了IPA空间的概念之后,就得考虑这个空间的Size了。虽然是个IPA,那也是PA,既然是PA,那么它的空间就要受到约束,起码不能比真是的物理内空间大,如手册的描述:

When a stage 2 translation occurs, the configured IPA size is specified by one of the following T0SZ values:

• If the IPA is in Non-secure or Realm address space, then VTCR_EL2.T0SZ

• If the IPA is in Secure address space, then VSTCR_EL2.T0SZ

The implemented PA size constrains all of the following:

• The maximum IPA size.

• The effective minimum T0SZ value, VTCR_EL2.T0SZ or VSTCR_EL2.T0SZ, used to specify the configured IPA size.

• The stage 2 initial lookup level.

而Implemented PA size又和系统寄存器的配置有关,如图1-3所示:

图1-3 Stage-2有效的情况下PA空间配置

Hypervisor配置好,码农就会根据需求对各个VM进行PA内存空间资源调配。主要是IO空间的分配和Normal类型内存空间的分配。GuestOS启动后就可以根据配置好的文件中的策略初始化自己的IPA空间。这部分主要和Hypervisor的实现方案以及GuestOS的类型相关,各个公司实现的方式都不太一样,这个大家明白大致原理就可以了。这里我们给出一种工程常用的分配方式,如图1-4所示,这种模式下IPA == PA,会降低Hypervisor的管理内存的难度,但是缺乏灵活性。

图1-4 一种典型的IPA空间的映射策略

1.3 Stage-2 Translation Table

GuestOS只能看到IPA的空间,他要使用IPA的资源就要记录在案,需要一个账本把这些事儿都记下来。看过前文的小伙伴应该都已经清楚了,在VMSA体系下这个账本就是页表(Translation Tables)。那么在虚拟化架构下,IPA到PA的空间同样需要映射,Hypervisor也需要通过页表或者翻译机制控制各种真是硬件资源的使用,也需要一个账本,这就是Stage-2 Translation Table。

1.3.1 Stage-2 多级页表架构

关于多级页表架构,希望大家先看一下前序文章: [A-11]ARMv8/ARMv9-Memory-多级页表架构。其实虚拟化框架下,Stage-2阶段的多级页表架构和非虚拟化的多级架构原理相通,只是配置起来更加的复杂。这里不展开讨论,只放一张图1-5供大家参考。

图1-5 Generalized view of a stage 2 address translation using the 4KB granule

1.3.2 Stage-2 页表描述符

同样在了解Stage-2页表的格式之前,希望大家先读一下前序文章[A-12]ARMv8/ARMv9-Memory-页表描述符(Translation table descriptor),这样大家就能够系统全面的掌握页表的含义。Stage-2的页表项也有着和Stage-1相似的结构,如图1-6所示。

图1-6 Stage-2 页表描述符

同样Stage-2的页表描述符和Stage-1也是既有联系也有区别,如手册中的描述:

The format of the translation tables used for stage 2 is very similar to that used for stage 1. However, some of the attributes are handled differently in stage 2 and the Type, Normal or Device, is encoded directly into table entry rather than via a MAIR_ELx register.

这部分也不展开讨论了,感兴趣的朋友还是要仔细的阅读手册去探究细节。

1.4 Combining Stage 1 and Stage 2 attributes

虚拟化的架构下VA要经过两本帐才能找到真实的物理空间。那么我们来思考这样一个场景:GuestOS要访问一个外部设备那么它申请访问的内存资源肯定是Device的,那么到了地址翻译的第二个阶段,Hypervisor会截获这个访问操作的,它也要分配相应的内存资源给这个Device类型的IPA。这就有意思了,Hypervisor是否一定会分配相同类型的内存资源给这个IPA呢?一致的情况下还好说,不一致的情况下又要怎么处理呢,如图1-7所示。

图1-7 Stage-1&2 内存类型不同的情况

类似的情况,比如权限等其他内存属性都可能会不同。ARM的体系下这块又是怎么处理的呢? 我们还是从手册中寻找答案:

1.4.1 策略一:合并

先看手册:

When virtualization is used, a virtual address goes through two stages of translation.

• One stage is under control of the OS, the other stage is under the control of the hypervisor.

• Both Stage 1 and Stage 2 tables include attributes.

• They need to combine these attributes.

• In the Arm architecture,the default is to use the most restrictive type.

按照这个策略,图1-7中的VA所在的内存区域就要按照Device类型对待,那么在运行时MMU访问VA的时候都会受到设备类型内存的限制。我们再举一个例子,图1-8中VA所在的区域就要按照只读权限进行对待了。

图1-8 Stage-1&2 内存读写权限不同的情况

1.4.2 策略二: 覆盖

在ARM的比较高版本的架构下,还提供了一个策略就是可以在Stage-2阶段进行覆盖,不过仅限于特殊的属性。先看手册:

For some cases, there are some control bits that override the normal behavior:

• HCR_EL2.CD. This makes all stage 1 attributes Non-cacheable.

• HCR_EL2.DC. This forces stage 1 attributes to be Normal, Write-Back Cacheable.

• HCR_EL2.FWB. This allows stage 2 to override the stage 1 attribute, instead of regular attribute combining.

1.4.3 异常处理

有些软件不套路出牌违反规则怎么办,如图1-9所示:

图1-9 Stage-1&2 内存读写权限不同的情况

按照策略一,那么这两种情况下,VA对应的内存区域都应该是只读区域。这个时候发生写操作,S-1和S-2都会发生异常。S-1条件下,异常事件会被GuestOS处理(El1-Exception Handler),而S-2条件下异常会被Hypervisor处理(El2-Exception Handler)。如果Stage-1和Stage-2都是RO属性,这个时候的异常将会被GuestOS处理(El1-Exception Handler)。

1.5 两级地址翻译(VA - IPA - PA)

1.5.1 两级页表遍历

我们把视角切换到系统总线,虚拟化架构下ARM中的地址翻译过程,是由内存管理单元(MMU)来完成的。MMU在ARM系统中扮演着至关重要的角色,它主要负责虚拟地址(VA)到物理地址(PA)的转换,以及内存访问权限、内存属性的判断和内存属性检查的控制。

For a two stage translation, all of the following:

— For a stage 1 translation, translate a VA to an IPA.

— For a stage 2 translation, translate an IPA to a PA for each of the stage 1 translation table lookups.

— For a stage 2 translation, translate an IPA to a PA for the stage 1 OA.

对于详细虚拟地址的翻译过程,可以参考前序文章[A-13]ARMv8/ARMv9-Memory-虚拟地址翻译(页表映射过程)。这里我们结合图1-10,做一下简要讨论。

图1-10  4k页-4级页表配置的虚拟地址的两级翻译过程

应该说ARM的架构还是个好人,费劲的事情它都给你做了。比如Stage-1阶段的页表遍历,这样就让两个阶段的耗时操作都被硬件吸收了。这样遍历一次之后,就可以在TLBs中进行缓存,这样下一次的这样耗时的遍历动作就不会再来一遍了。码农就是按照要求填充好页表和相关的系统寄存器,就可以高枕无忧矣。

1.5.2 多空间的地址翻译

让我们再把视角切换到VMSA的内存空间视角,如图1-11所示。当系统被配置为虚拟化的模式之后,GuestOS所在的EL1&0空间就需要两次翻译才能将一个VA映射为PA。因为一些原因当CPU的上下文切换到EL2和EL3的空间,此时PE-Core发射VA只需要一次翻译就能找到对应的PA。这里对比一下,希望加深大家对两级地址翻译架构的理解。

图1-11  一种典型内存内存空间配置

结语

本文我们介绍了Stage-2阶段的地址翻译工作涉及到的一些技术点,我们介绍了IPA空间、Stage-2页表架构和格式,以及两级地址翻译过程中的一些课题的处理策略、最后介绍了不同视角下的两级地址翻译过程,以及和其他地址空间地址翻译过程的关系。关于两级地址翻译机制还有可以研究的敌法,比如Stage-1 关闭的配置下,VA的翻译过程等等,限于篇幅和重要性,这里我们暂时不展开讨论,对这个感兴趣的朋友,可以自行阅读手册。希望大家阅读完本文后对ARM的内存虚拟化机制能有更加深刻的理解。下一篇文章,我们还是回到总线架构层面,看看虚拟化架构下,其他Master是如何访问内存空间的。谢谢大家,请保持关注。

Reference

[00] <aarch64_virtualization_100942_0100_en.pdf>

[01] <Armv8-A-virtualization.pdf>

[02] <learn_the_architecture_aarch64_virtualization.pdf>

[03] <DDI0487K_a_a-profile_architecture_reference_manual.pdf>

[04] <DEN0024A_v8_architecture_PG.pdf>

[05] <learn_the_architecture_aarch64_memory_model.pdf>

[06] <80-V-Kvm-ARM-zh0005_基于armv8的kvm实现分析(五)-内存虚拟化.pdf>

[07] <80-V-KVM-k0005_Linux虚拟化KVM-Qemu分析(五)-内存虚拟化.pdf>

[08] <79-LX-LK-z0002_奔跑吧Linux内核-V-2-卷1_基础架构.pdf>

[09] <learn_the_architecture_aarch64_memory_management.pdf>

Glossary

MMU             - Memory Management Unit

TLB               - translation lookaside buffer

VIPT              - Virtual Index Physical Tag

VIVT              - Virtual Index Virtual Tag

PIPT               - Physical Index Physical Tag

VA                   -  Virtual Address

PA                   -  Physical Address

IPS                  - Intermediate Physical Space

IPA                  - Intermediate Physical Address

VMID               - virtual machine identifier

TLB                  - translation lookaside buffer(地址变换高速缓存)

VTTBR_EL2     - Virtualization Translation Table Base Registers(ArmV8 寄存器)

ASID                 - Address Space Identifier (ASID)

浩瀚架构师
和大家一起探索这个神奇的世界。