1. 前言
最近在学习并整理ATF的BL1、BL2阶段,其中ls_setup_page_tables用到了虚拟地址的概念。因此就先整理一下。全文根据ARMV8手册《Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile》列出常用名称、概念以及主要用法,由于描述的需要,文中仅有部分片段提到虚拟化的概念(作者不是很熟)。
2. 虚拟地址的概念
- 物理地址:The address of a location in a physical memory map. That is, an output address from the PE to the
memory system。物理内存映射中某个位置的地址,是硬件真实使用的地址。 - 虚拟地址: Virtual addresses are those used by you, and the compiler and linker, when placing code in
memory(An address used in an instruction, as a data or instruction address)。 程序指令中使用的地址,如数据地址或指令地址。
为什么要有一个虚拟地址的概念呢?
(1)直接操作物理地址
假设CPU直接操作的是物理地址,那就无法支持多进程了。因为假设进程A和进程B都要操作某一物理地址,其中任何一个进程改写这个地址,都会影响到另一个进程的执行,造成的结果是不可控的。
(2)使用虚拟地址访问
操作系统为了解决上述问题,提出了虚拟内存的概念。通过使用MMU, OS划分出一段地址区域, 在这块地址区域中, 每个进程看到的内容都不一定一样(每一个进程都有一个独立的地址空间)。使用MMU的好处在于:
- 让每个进程拥有了相同的、独立内存空间,相互之间不会干扰
- 读写内存更安全。由于系统和MMU的限制,使得进程无法操作到其他进程的数据。
- 不连续的物理空间可以映射成连续的虚拟地址空间
- 进程分配的内存空间只有在实际使用时,才会触发缺页异常来分配实际物理空间,从而最大程度减少了内存空间的浪费。
3. AArch64虚拟内存系统架构
虚拟内存系统架构(VMSA: Virtual Memory System Architecture)提供了一个 内存管理单元(MMU),它用于对PE访问的内存进行控制,如: 地址转换、访问权限以及决定并检查与访存地址相关的内存属性(memory attribute,可理解为地址对应的内存域的性质,例如该内存域的数据一致性需要满足什么要求等)。地址转换的过程将PE使用的虚拟地址(VAs)映射到物理内存系统的物理地址(PAs)。
VMSAv8-64,这是一种Armv8 VMSA,适用于使用AArch64的异常级别。但是,当较高的异常级别使用AArch64(因此使用VMSAv8-64)时,较低的异常级别可以使用AArch32。
3.1 关于虚拟内存系统架构(VMSA)
3.1.1 Armv8 VMSA命名
名称 | 解释 |
---|---|
VMSAv8 | 描述ARMv8地址转换方案,包括Stage 1 和 Stage 2两个阶段 |
VMSAv8-32 | 使用AArch32的异常级别管理的 单级 地址转换的方案 |
VMSAv8-64 | 使用AArch64的异常级别管理的 单级 地址转换方案 |
3.1.2 在Armv8的VMSA中,一些异常级别使用的是AArch32
VMSAv8-64,是一种Armv8 VMSA,适用于an使用AArch64的异常级别。但是,当较高的异常级别使用AArch64(因此使用VMSAv8-64)时,较低的异常级别可以使用AArch32。
3.1.3 VMSA地址类型和地址空间
VMSA地址类型和地址空间有以下三种:
地址类型 | 含义 | 有关解释 |
---|---|---|
Virtual address (VA):虚拟地址 | 在指令中使用的地址,如数据地址或指令地址,是虚拟地址(VA)。这意味着在PC、LR、SP或ELR中保存的地址是VA | 在AArch64状态下,VA的最大地址宽度为48位,当FEAT_LVA(Large VA support)被实现并且使用64KB的转换颗粒时,VA的最大地址宽度为52位。 转换阶段只能支持一个VA范围: (1) 虚拟地址有48bit,从0x0000_0000_0000_0000到0x0000_FFFF_FFFF_FFFF; (2) 如果实现了FEAT_LVA并使用了64KB转换颗粒,那么对于支持单个VA范围的转换机制,52位VA宽度给出的VA范围为0x0000000000000000 to 0x000FFFFFFFFFFFFF ; 转换阶段能支持两个VA范围: 对于一个支持两个VA子程序的转换阶段,一个在完整64位地址范围的底部,一个在顶部,如下: 底部VA范围从地址0x0000000000000000开始: (1)当最大VA宽度为48位,VA范围为0x0000000000000000- 0x0000FFFFFFFFFFFF; (2) 当最大VA宽度为52位,VA范围为0x0000000000000000- 0x000FFFFFFFFFFFFF; 顶部的VA范围截至到地址 0xFFFFFFFFFFFFFFFF: (1)当最大VA宽度为48位,VA范围为0xFFFF000000000000- 0xFFFFFFFFFFFFFFFF; (2) 当最大VA宽度为52位,VA范围为0xFFF0000000000000- 0xFFFFFFFFFFFFFFFF |
Intermediate physical address (IPA):中间物理地址 | 如果不支持Stage 2转换,那么IPA == PA。如果支持Stage2,那么IPA: - Stage 1 的OA (Output address) - Stage 2 的IA (Input address) | 无 |
Physical address (PA):物理地址 | 物理内存映射中某个位置的地址。也就是说,从PE到内存系统的一个输出地址 | 无 |
-
ID_AA64MMFR0_EL1.PARange字段表示实现的PA大小,如图所示:
-
TCR_ELx.{I} PS字段为该转换阶段最大输出地址大小,如图所示:
3.1.4 AArch64状态下的地址标签(Address tagging )
地址标签的使用控制如下(TBI:Top Byte Ignored):
支持的VA rangs | 说明 |
---|---|
two VA ranges | VA的bit [55]的值确定控制地址标签使用的寄存器位,如下所示: (1) VA[55]==0 : TCR_ELx.TBI0决定是否使用地址标签。如果启用了阶段1转换,则TTBR0_ELx保存用于转换地址的转换表的基地址 (2) VA[55]==1 : TCR_ELx.TBI1决定是否使用地址标签。如果启用了第1阶段转换,则TTBR1_ELx保存用于转换地址的转换表的基地址 |
single VA range | TCR_ELx.TBI决定是否使用地址标签。如果启用了阶段1转换,TTBR0_ELx保存用于转换地址的转换表的基地址。 |
3.2 64地址转换系统
3.2.1 关于VMSAv8-64地址转换系统
3.2.1.1 AArch64转换机制
1. VMSAv8-64地址转换组织方式
在VMSAv8-64地址转换系统中,地址转换系统的地址转换组织方式有两种:
址转换组织方式 | 解释 |
---|---|
单一的地址转换方式 | 将地址从虚拟地址(VirtualAddress, VA)直接转换为物理地址(Physical Address,PA) |
两阶段地址转换 | 第一阶段将虚拟地址转换为中间物理地址(IntermediatePhysical Address , IPA), 第二阶段将中间物理地址转换为物理地址 |
2. VMSAv8 AArch64地址转换机制、转换阶段和相关控制
在VMSAv8-64地址转换系统中,地址转换系统的地址转换机制有9种:
使用的转换机制 | 支持转换阶段 | 支持VA范围数 | 应用时特殊寄存器值 |
---|---|---|---|
Secure EL1&0 translation regime, when EL2 is disabled | stage 1 | 2 | HCR_EL2.{E2H, TGE} is {0,0} |
Non-secure EL1&0 translation regime, when EL2 is disabled | Stage 1 | 1 | (1)HCR_EL2.{E2H, TGE} is {0,0} (2)memory access will be Non-secure when SCR_EL3.NS is 1 |
Secure EL1&0 translation regime, when EL2 is enabled | Stage 1 Stage 2 | 2 1 | HCR_EL2.{E2H, TGE} is {0, 0} |
Non-secure EL1&0 translation regime, when EL2 is enabled | Stage 1 Stage 2 | 2 1 | HCR_EL2.{E2H, TGE} is {0, 0} |
Secure EL2&0 translation regime | Stage 1 | 2 | HCR_EL2.{E2H, TGE} is {1,1} HCR_EL2.E2H is 1 |
Non-secure EL2&0 translation regime | Stage 1 | 2 | HCR_EL2.{E2H, TGE} is {1,1} HCR_EL2.E2H is 1 |
Secure EL2 translation regime | Stage 1 | 1 | (1) implementations don’t include FEAT_VHE (2) FEAT_VHE is implemented and HCR_EL2.E2H is 0. |
Non-secure EL2 translation regime | Stage 1 | 1 | (1) implementations don’t include FEAT_VHE (2) FEAT_VHE is implemented and HCR_EL2.E2H is 0. |
Secure EL3 translation regime | stage 1 | 1 | 无 |
3. 关于地址转换和支持的输入地址范围
对于单级地址转换,转换表基址寄存器(TTBR_ELx)指示从输入地址(IA)到输出地址(OA)的映射所需的第一个转换表的开始。 对于支持两个VA范围的地址转换阶段,每个VA范围都是从IA到OA的独立映射。
支持VA范围数 | 寄存器 | 支持大小 | 解释 |
---|---|---|---|
1个 | TTBR_ELx | - - - | Translation table base register |
2个 | TTBR0_ELx TTBR1_ELx | 0x0000_0000_0000_0000 - (2^(64-T0SZ) - 1) (2^64 - 2^(64-T1SZ)) to 0xFFFF_FFFF_FFFF_FFFF | TTBR0_ELx : 用户特定进程的地址(用户态). 每个进程维护一个单独的1级转换表。在上下文切换中 : (1) TTBR0_ELx被更新为指向新上下文的第1级转换表 (2) 一旦此更改更改了转换表的大小,则更新TCR_ELx (3) 更新 CONTEXTIDR_ELx TTBR1_ELx : 用于操作系统和I/O地址,在上下文切换时不会更改. |
4. VMSAv8-64支持的转换表格式
VMSAv8-64转换表格式支持:
- 多达四个级别的地址查找;
- 转换粒度支持4KB,16KB或64KB。
- 输入地址:
(1)如果实现了FEAT_LVA并且使用了64KB转换粒度,则最多为52位。
(2)否则,最多48位。 - 输出地址:
(1)如果实现了FEAT_LPA并且使用了64KB转换粒度,则最多为52位。
(2)否则,最多48位
3.2.1.2 内存转换粒度大小
1. 表示stage1中的支持颗粒大小的寄存器
粒度大小 | 支持:字段 | 值 | 含义 |
---|---|---|---|
4KB | ID_AA64MMFR0_EL1.TGran4 | 0b0000 0b1111 | 4KB granule size supported. 4KB granule size not supported . |
16KB | ID_AA64MMFR0_EL1.TGran16 | 0b0000 0b1111 | 16KB granule size supported. 16KB granule size not supported . |
64KB | ID_AA64MMFR0_EL1.TGran64 | 0b0000 0b1111 | 64KB granule size supported. 64KB granule size not supported . |
2. 表示stage2中的支持颗粒大小的寄存器
粒度大小 | 支持:字段 | 值 | 含义 |
---|---|---|---|
4KB | ID_AA64MMFR0_EL1.TGran4_2 | 0b0000 0b1111 | 4KB granule size supported at stage 2. 4KB granule size not supported at stage 2 . |
16KB | ID_AA64MMFR0_EL1.TGran16_2 | 0b0000 0b1111 | 16KB granule size supported at stage 2. 16KB granule size not supported at stage 2 . |
64KB | ID_AA64MMFR0_EL1.TGran64_2 | 0b0000 0b1111 | 64KB granule size supported at stage 2. 64KB granule size not supported at stage 2. |
使用较大的颗粒大小可以减少地址查找级别所需的最大数量,因为:
- 增加的转换表大小意味着转换表包含更多条目。这意味着一次查找可以解析输入地址的更多位。
- 增加的页面大小意味着需要更多的最小有效地址位来寻址页面。这些地址位从输入地址平面映射到输出地址,因此不需要转换
Arm建议内存映射外设按操作系统或hypervisor所支持的最大粒度的整数倍来分隔,以便独立地管理每个外设。
颗粒大小对地址转换过程影响如表:
属性 | 4 kb粒度 | 16 kb粒度 | 64 kb粒度 | 注释 |
---|---|---|---|---|
转换表中有最大条目数 (项) | 512 | 2048 (2K) | 8192 (8K) | - |
每级lookup最大可解析地址位 | 9 | 11 | 13 | 29=512 , 211=2K , 213=8K |
页大小 | 4KB | 16KB | 64KB | |
页地址范围 | VA[11:0]= PA[11:0] | VA[13:0]=PA[13:0] | VA[15:0]=PA[15:0] | 212 = 4K , 214=16K,216=64K |
3. 三种转换粒度示意图
-
4KB转换粒度示意图
-
16KB转换粒度示意图
-
64KB转换粒度示意图
4. 粒度对转换表寻址的影响
粒度 | 最大支持Level | 每个级别查找最大解析的IA宽度 | Page Offset |
---|---|---|---|
4kB | 4 | 9bit | IA[11:0] == OA[11:0] |
16kB | 4 | 11bit | IA[13:0] == OA[13:0] |
64kB | 3 | 13bit | IA[15:0] == OA[15:0] |
3.2.1.3 转换表和转换的过程
部分被经常访问的转换表表项被存储在TLB(Translation Lookaside Buffer,即页面高速缓存)中,而转换过程中第一个被查询的转换表在内存中的基地址被存储在TTBR(Translation Table Base Register,即页表基址寄存器)中。一次输入地址到输出地址的转换需要一系列转换表查询(translationtable lookup ),这一系列查询操作被称为转换表遍历(translation table walk),最后一次查询将返回输出地址的高bit位、被访问的内存域的属性和访问控制信息。非最后一次查询将会查询到下一级的转换表的基址和层级属性信息(如下一级转换表在安全内存中还是非安全内存中),一个典型的查询过程如下图所示:
VMSAv8-64中查找转换表,对转换表条目执行64位原子访问(即一个条目占8个字节)。这意味着转换表条目被视为64位对象,以达到endianness的目的。
几个核心寄存器的说明:
寄存器 | 说明 |
---|---|
SCTLR_ELx.EE | 转换表查找的大小端 |
TCR_ELx | 内存可缓存性和可共享属性 |
TTBR_ELx | 用于初始查找的转换表基地址 |
3.2.1.4 VMSAv8-64 address translation stages(以4KB粒度为例)
1. Stage 1(一阶地址转换)
- TTBR 寄存器提供Level 0查找的基地址,通过此基地址和IA[n:39] => 查找到Level 1基地址
- Level 1基地址结合IA[38:30]=> 查找到Level2 的基地址
- Level 2基地址结合IA[29:21]=> 查找到Level3 的基地址
- Level 3基地址结合IA[20:12]=> 查找物理页所在地址
- 最后得到需要的物理地址PA[47:0] <= OA[47:12] + IA[11:0]
- Level 1支持1GB的内存block,Level 2支持2MB的内存block
2. Stage 2(二阶地址转换)
- Stage 2有级联table的概念,可以减少level的级数
- 所谓级联就是假如有IA[40:0],而Level1解析地址段为IA[38:30],超过了2个bit,而240 = 22 * 238,所以相当于要22个这样的translation table来实现级联解析。ARMv8规定,Stage 2最多支持4-bit级联,也就是最大级联2^4 == 16个translation table级联解析.以达到减少查找level的目的.
- VTTBR_EL2寄存器提供初始Level查找基地址,Stage 2只为EL2服务
- 同Stage 1,Level 1支持1GB的内存block,Level 2支持2MB的内存block
3.3 VMSAv8-64转换表格式描述符
只列出 48-bit OAs的例子(当前主流,能表示的内存大小已足够大256TB),
3.3.1 VMSAv8-64中描述符的类型
1. VMSAv8-64转换表level 0、level 1级和level2 描述符类型
描述符类型 | bit[1] | bit[0] | 说明 |
---|---|---|---|
Invalid | - | 0 | 无效描述符,任何访问该地址的尝试都会生成转换错误 |
Block | 1 | 0 | 提供内存块的基地址和该内存区域的属性 |
Table | 1 | 1 | 提供下一级转换表的地址,对于阶段1的转换,提供该转换的一些属性 |
2. VMSAv8-64 转换表level 3描述符类型
描述符类型 | bit[1] | bit[0] | 说明 |
---|---|---|---|
Invalid | - | 0 | 无效描述符,任何访问该地址的尝试都会生成转换错误 |
Reserved | 0 | 1 | 保留 |
Page | 1 | 1 | 提供4KB、16KB或64KB内存页的地址和属性 |
3.3.2 各个level支持的Block属性( level3 转换表不支持Block描述符 )
粒度 | 说明 |
---|---|
4KB | level0 转换表不支持Block描述符 level 1 Block转换表k描述了相关的1GB输入地址范围的映射 level 2 Block转换表k描述了相关的2MB输入地址范围的映射 |
16KB | level0 、level1转换表不支持Block描述符 level 2 Block转换表k描述了相关的32MB输入地址范围的映射 |
64KB | 不支持 level0 查找 如果实现了FEAT_LPA : (1) level 1 Block转换表k描述了相关的4TB输入地址范围的映射; (2) level 2 Block转换表描述了相关的512MB输入地址范围的映射; 如果未实现了FEAT_LPA : (1) level 1 转换表不支持Block描述符; (2) level 2 Block转换表描述了相关的512MB输入地址范围的映射 |
3.3.3 VMSAv8-64转换表格式描述符中的内存属性字段
1. stage1 VMSAv8-64 Table描述符中的下一级属性
字段 | bit位 | 说明 |
---|---|---|
NSTable(Non-secure) | [63] | 安全模式标志位: (1) NSTable == 0 :定义的表地址在安全PA空间中 (2) NSTable == 1 :定义的表地址在非安全PA空间中 |
APTable(Access permissions) | [62:61] | 后续查找级别的访问权限限制 APTable[0] is RES0:In the EL2 translation regime |
UXNTable or XNTable (Execute-never or Unprivileged execute-never ) | [60] | 对后续查找级别的执行(XN)权限限制 Stage 1 支持两个VA ranges :这个字段是UXNTable; Stage 1 支持一个VA ranges :这个字段是XNTable |
PXNTable | [59] | 限制XN的特权bit,P(privileged)是指特权 |
2. stage1 VMSAv8-64中的 Block 和 Page 描述符中的属性字段
字段 | bit位 | 说明 |
---|---|---|
PBHA(Page-based Hardware Attributes) | [62:59] | 基于页面的硬件属性位。当没有实现FEAT_HPDS2(Translation table page-based hardware attributes)时,这些位被忽略 |
XN or UXN(Execute-never or Unprivileged execute-never) | [54] | executor-never 控制是否可以从内存区域执行指令 |
PXN(Privileged execute-never) | [53] | 特权execute-never bit位 只有在转换stage1能够支持两个VA范围时,该字段才有效。stage1只能支持一个VA范围时值为RES0 |
Contiguous | [52] | 表示相邻的转换表条目指向具有相同权限和属性的连续输出地址范围 |
DBM(Dirty Bit Modifier) | [51] | 脏状态指示是否修改了内存的页或段,脏状态可以由硬件管理,在硬件中管理脏状态的地方,脏状态信息使用访问许可位编码AP[2]和S2AP[1]与DBM位结合 |
GP(Guarded Page) | [50] | (1)在stage1中如果实现了FEAT_BTI(Branch Target Identification),那么这个字段将出现在Block和Page转换表条目中。否则,该字段为RES0。 (2) 在第2阶段的Block和Page转换表条目中,这个字段是RES0 |
nT | [16] | Block转换条目:在stage1中如果实现了FEAT_BBM(Branch Target Identification),那么这个字段将出现在Block转换表条目中。否则,该字段为RES0。 |
nG(not global) | [11] | 非全局bit位。如果使用此描述符的查找被缓存在TLB中,确定TLB条目是应用于全局ASID值,还是仅应用于当前ASID值 |
AF(Access flag) | [10] | 访问标志指示自从对应应转换表描述符中的访问标志设置为0后,何时第一次访问内存的页或段。Armv8.0要求软件管理访问标志。 这意味着每当尝试将其访问标志值为0的转换表描述符条目读入TLB时,都会生成访问标志错误。访问标记机制期望在发生访问标记错误时,软件将导致该错误的转换表条目中的访问标记重置为1。 这样可以防止下次访问存储位置时发生故障。 将访问标志设置为0的条目永远不会保存在TLB中,这意味着在设置该标志之后,软件不必从TLB中清除该条目。 |
SH(Shareability field) | [9:8] | 用来指示一个内存位置对于一些处理器是否是可共享的。共享意味着需要硬件保证一个内存位置中的内容对一定范围内可访问该位置的多个处理器是一致。Shareability属性有Non-shareable、InnerShareable和Outer Shareable三个选项 |
AP[2:1](Access flag) | [7:6] | 数据访问权限位: (1) Armv8转换表描述符格式将AP[2:1]定义为访问权限位,而没有定义AP[0]位; (2) AP[1]仅对可支持两个VA范围的转换机制的stage1有效。当stage 转换只能支持一个VA范围时,默认值是RES1 |
NS(Non-secure) | [5] | 对于从安全状态访问内存,指定输出地址是在安全地址映射中还是在非安全地址映射中: (1) NS == 0 访问安全PA空间 (2) NS == 1 访问非安全PA空间 。 对于不安全的转换机制,以及从不安全内存中获取的转换表描述符,对应的位是RES0,并被PE忽略。无论位的值是多少,访问的都是不安全的内存 |
AttrIndx[2:0](Stage 1 memory attributes index) | [4:2] | stage1内存属性索引字段,用于MAIR_ELx |
3. stage2 VMSAv8-64中的 Block 和 Page 描述符中的属性字段
字段 | bit位 | 说明 |
---|---|---|
PBHA[3:1](Page-based Hardware Attributes) | [62:60] | 基于页面的硬件属性位。 (1)当未应用FEAT_HPDS2时,这些位被忽略并保留给System MMU使用; (2)当应用FEAT_HPDS2时,VTCR_EL2在EL1&0第2阶段转换表中的每个PBHA位都有一个控制位 |
PBHA[0] | [59] | 基于页面的硬件属性位。 (1)当未应用FEAT_HPDS2时,该位被忽略; (2)当应用FEAT_HPDS2时,VTCR_EL2在EL1&0 stage2转换表中对此位具有控制位 |
XN[1:0](execute-never) | [[54:53]] | execute-never bit位 如果没有应用FEAT_XNX,则为RES0 |
Contiguous | [52] | 表示相邻的转换表条目指向具有相同权限和属性的连续输出地址范围 |
DBM(Dirty Bit Modifier) | [51] | 脏状态指示是否修改了内存的页或段 |
nT | [16] | Block转换条目:在stage2中如果实现了FEAT_BBM(Branch Target Identification),那么这个字段将出现在Block转换表条目中。否则,该字段为RES0。 |
AF(Access flag) | [10] | 访问标志指示自从对应应转换表描述符中的访问标志设置为0后,何时第一次访问内存的页或段。 |
SH(Shareability field) | [9:8] | 用来指示一个内存位置对于一些处理器是否是可共享的。 |
S2AP[2:1](Access flag) | [7:6] | Stage 2 数据访问权限位 |
MemAttr | [4:2] | stage2内存属性,用于MAIR_ELx |
3.4 内存访问控制
主要是对3.3节 转换表描述符中定义数据访问和指令获取的访问权限的字段的进一步解释。
3.4.1 关于访问权限的总述
访问权限位控制对应内存区域的访问。在VMSAv8-64转换中:
- 在stage1转换中,使用AP[2:1]定义数据访问权限。(访问权限字段AP[2:1]的表述方法是为了与VMSAv8-32短描述符转换表格式一致,请参阅第G5-5979页的VMSAv8-32短描述符转换表格式。VMSAv8-64转换表格式**=未定义AP[0]位**);
- 在stage2中,使用**S2AP[1:0]**来定义数据访问权限;
- 使用UXN、XN和PXN字段定义指令获取的访问控制;
3.4.2 PSTATE.PAN、PSTATE.UAO、PSTATE.BTYPE的解释
1. PSTATE.PAN(Privileged Access Never (PAN))
- 当PSTATE.PAN的值为1时,则从EL1或EL2 对 可在EL0进行数据访问的虚拟内存地址的任何特权数据访问都会生成权限错误;
- 当PSTATE.PAN的值为0时,转换系统与Armv8.0相同;
- 当应用FEAT_PAN时,SPSR_EL1.PAN、SPSR_EL2.PAN和SPSR_EL3.PAN位用于异常返回,DSPSR_EL0寄存器用于进入或退出调试状态;
- 当应用FEAT_PAN时,SCTLR_EL1.SPAN和SCTLR_EL2.SPAN位用于控制PAN位用于设置EL1或EL2的异常;
- 当HCR_EL2.{E2H,TGE}=={1,1},SCTLR_EL1.SPAN和SCTLR_EL2.SPAN被忽略。
2. PSTATE.UAO(User Access Override (UAO) )
- 当PSTATE.UAO的值为1时,在EL1处执行的加载/存储无特权指令,或在EL2执行且HCR_EL2.{E2H,TGE}的有效值为{1,1}时,它受适用于执行它的异常级别的内存访问权限的约束,而不是受EL0访问权限的约束。这意味着“加载/存储非特权”指令与相应的“加载/存储”寄存器指令具有相同的访问权限。请参阅第C3-211页的无特权加载/存储和第C3-207页的加载/存储寄存器;
- 当应用FEAT_UAO且PSTATE.UAO为0时,它对任何“装入/存储”非特权指令的描述行为都没有影响;
- 将相应的UAO位添加到SPSR_EL1,SPSR_EL2和SPSR_EL3,以返回异常,并添加DSPSR_EL0,以进入或退出调试状态;
从AArch64状态变为AArch64状态的异常,会将PSTATE.UAO复制到SPSR_ELx.UAO,然后将其设置为0。
从AArch32状态变为AArch64状态的异常:
- PSTATE.UAO设置为0。
- SPSR_ELx.UAO设置为0。
从AArch64状态返回到AArch64状态的异常时,将SPSR_ELx.UAO复制到PSTATE.UAO。
3. PSTATE.BTYPE(Branch target identification)
当应用FEAT_BTI时,在执行一条指令时,内存区域的保护状态和该指令访问的寄存器决定了在指令执行结束时设置的PSTATE.BTYP字段,如表所示:
3.4.3 数据访问权限控制
1. 防止EL0访问地址映射的一半
如果应用了FEAT_E0PD(Preventing EL0 access to halves of address maps),则TCR_ELx.{E0PD0,E0PD1}字段可以阻止对TTBR0_ELx或TTBR1_ELx转换的地址的非特权访问。如果访问被阻止,则该故障将被报告为0级故障,并且无论地址是否存在于TLB中,都应花费相同的时间来生成,以减轻使用错误计时的攻击。
2. stage 1 转换的AP[2:1]数据访问权限
(1) 在VMSAv8-64中,对于适用于EL0和更高异常级别的转换机制,AP[2:1]位控制 stage1 的数据访问权限,并且:
- AP[2]选择只读和读/写访问。
- AP[1]在应用程序级别(EL0)控制和更高的异常级别控制之间进行选择。
(2 )对于单个异常级别访问的转换机制,AP[2]确定stage1的数据访问权限,而AP[1]是RES1,这意味着它被硬件忽略,并被视为1。
3. S2AP数据访问权限
在安全或非安全的EL1&0中,当启用EL2时,转换机制,当启用stage2 地址转换时,stage2 转换表描述符中的S2AP字段定义数据访问权限,如表D5-30所示。在此表中,None项表示任何访问都会生成权限错误。
4.数据访问权限的分层控制
- 在VMSAv8-64转换表中,在某个级别的转换表查找,可以对在后续查找级别上允许的条目设置限制。
- 但是,当FEAT_HPDS(Hierarchical permission disables)应用时,当TCR_ELx.HPD {0}字段的值是1或TCR_ELx.HPD1字段的值是1时,将为受控的转换阶段**禁用数据访问权限的分层控制*,则本小节中的信息不适用。
- 这些限制仅适用于同一转换阶段的后续查找级别。 APTable [1:0]字段限制访问权限,如表D5-31所示。 如表脚注中所述,对于仅适用于单个异常级别的转换机制,APTable [0]为RES0,这意味着它会被硬件忽略。
3.4.4 指令执行的访问权限(Access permissions for instruction execution)
3.4.5 访问标志(Access flag)
3.4.6 指令执行的访问权限(dirty state)
3.4.7Block转换条目(Block translation entry)
3.4.4 ~3.4.7小节比较容易理解,参见3.3节中各种描述符对应的bit位解释。
3.5 Translation Lookaside Buffers (TLBs)
Translation Lookaside Buffers (TLBs) 通过缓存转换表遍历的结果来降低内存访问的频率。 TLB充当转换表信息的缓存。
为了提高TLB的性能,将TLB分成Global和process-specific。global 是指常驻在tlb中不会被刷出的,例如内核空间的地址转换,process-specific 是指每个进程独有的地址空间,当发生进程切换的时候,这部分tlb可以被刷出。为了支持process-specific的tlb,arm提出了ASID(Adress Space ID)的硬件解决方案,这样TLB就可以识别出进程的TLB entry。ASID是通过位图来管理的,已经分配的ASID 都记录在asid_map中。
在进程切换的时候__schedule()->context_switch()->switch_mm()->check_and_switch_context中可以看到asid的应用
void check_and_switch_context(struct mm_struct *mm, unsigned int cpu)
参见:ASID
在VMSA实现中,系统软件可以将支持两个VA范围的转换阶段使用的虚拟内存映射划分为全局和非全局区域,由转换表中的nG位表示:
nGbit位的值 | 解释 |
---|---|
nG == 0 | 转换是全局的,这意味着该地区对所有进程都是可用的。 |
nG == 1 | 转换是非全局的,或特定于进程的,这意味着它与当前ASID相关,由: (1)TTBR0_ELx.ASID,如果TCR_ELx.A1的值为0。 (2)TTBR1_ELx.ASID,如果TCR_ELx.A1的值为1。 |
需要注意的是:选定的ASID适用于nG位值为1的任何地址的转换,无论该地址是基于TTBR0_ELx还是基于TTBR1_ELx转换。