AArch32/AArch64虚拟内存系统架构(六)
@
- 1. 前言
- 2. 虚拟地址的概念
- 3. 虚拟内存系统架构
- 3.1 关于虚拟内存系统架构(VMSA)
- 3.1.1 Armv8 VMSA命名
- 3.1.2 在Armv8的VMSA中,一些异常级别使用的是AArch32
- 3.1.3 VMSA地址类型和地址空间
- 3.1.4 AArch64状态下的地址标签(Address tagging )
- 3.2 64位地址转换系统
- 3.3 32位地址转换系统
1. 前言
最近在学习并整理ATF的BL1、BL2阶段,其中ls_setup_page_tables用到了虚拟地址的概念。因此就先整理一下。全文根据ARMV8手册《Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile》列出常用名称、概念以及主要用法,由于描述的需要,文中仅有部分片段提到虚拟化的概念(作者不是很熟)。
本节重点讲解AArch64虚拟内存系统架构,简单介绍AArch32虚拟内存系统架构(当前主流内核都是使用AArch64,搭配用户态32位/64位),如需深入了解,请参考ARMV8参考手册《Chapter G5- The AArch32 Virtual Memory System Architecture》。
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. 虚拟内存系统架构
虚拟内存系统架构(VMSA: Virtual Memory System Architecture)提供了一个 内存管理单元(MMU),它用于对PE访问的内存进行控制,如: 地址转换、访问权限以及决定并检查与访存地址相关的内存属性(memory attribute,可理解为地址对应的内存域的性质,例如该内存域的数据一致性需要满足什么要求等)。地址转换的过程将PE使用的虚拟地址(VAs)映射到物理内存系统的物理地址(PAs)。
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,适用于使用AArch64的异常级别。但是,当较高的异常级别使用AArch64时,较低的异常级别也可以使用AArch32。
3.1.3 VMSA地址类型和地址空间
VMSA地址类型和地址空间有以下三种:
地址类型 | AArch64 | AArch32 |
---|---|---|
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 |
在指令中使用的地址,如数据地址或指令地址,称为虚拟地址(VA)。PC、LR或SP中保存的地址就是VA。 对于AArch32状态,最大的VA空间是4GB,最大的VA范围是0x0000000 - 0xffffffff。 |
Intermediate physical address (IPA):中间物理地址 | 如果不支持Stage 2转换,那么IPA == PA。如果支持Stage2,那么IPA: - Stage 1 的OA (Output address) - Stage 2 的IA (Input address) |
在提供两个地址翻译阶段的翻译机制中,IPA是Stage 1 转换之后的地址,是Stage 2 转换的输入地址。 在只提供地址翻译一个阶段的翻译体制中,IPA与PA是相同的。 VMSAv8-32实现仅提供一个stage地址转换情形如下: • 未应用EL2; • 在Secure状态下执行时; • 在Hyp mode中执行时 |
Physical address (PA):物理地址 | 物理内存映射中某个位置的地址。也就是说,从PE到内存系统的一个输出地址 | 安全或非安全内存映射中某个位置的地址。也就是说,从PE到内存系统的一个输出地址 |
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 AArch64转换机制
3.2.1.1 VMSAv8-64地址转换组织方式
在VMSAv8-64地址转换系统中,地址转换系统的地址转换组织方式有两种:
址转换组织方式 | 解释 |
---|---|
单一的地址转换方式 | 将地址从虚拟地址(VirtualAddress, VA)直接转换为物理地址(Physical Address,PA) |
两阶段地址转换 | 第一阶段将虚拟地址转换为中间物理地址(IntermediatePhysical Address , IPA), 第二阶段将中间物理地址转换为物理地址 |
3.2.1.2 VMSAv8 AArch64地址转换机制、转换阶段和相关控制
在VMSAv8-64地址转换系统中,地址转换系统的地址转换机制有9种:
使用的转换机制 | 支持转换阶段 | 支持VA范围数 | 说明 |
---|---|---|---|
Secure EL1&0 translation regime, when EL2 is disabled | stage 1 | 2 | 当HCR_EL2{E2H, TGE}的值为{0,0}时,从EL1或EL0访问内存。 |
Non-secure EL1&0 translation regime, when EL2 is disabled | Stage 1 | 1 | 当HCR_EL2{E2H, TGE}的值为{0,0}时,从EL1或EL0访问内存。 |
Secure EL1&0 translation regime, when EL2 is enabled | Stage 1 Stage 2 |
2 1 |
当HCR_EL2{E2H, TGE}的值为{0,0}时,从EL1或EL0访问内存。 |
Non-secure EL1&0 translation regime, when EL2 is enabled | Stage 1 Stage 2 |
2 1 |
当HCR_EL2{E2H, TGE}的值为{0,0}时,从EL1或EL0访问内存。 |
Secure EL2&0 translation regime | Stage 1 | 2 | (1) 当HCR_EL2{E2H, TGE}的值为{1,1}时,从EL1或EL0访问内存。 (2) 当HCR_EL2.E2H的值为1时,从EL2访问内存。 |
Non-secure EL2&0 translation regime | Stage 1 | 2 | (1) 当HCR_EL2{E2H, TGE}的值为{1,1}时,从EL1或EL0访问内存。 (2) 当HCR_EL2.E2H的值为1时,从EL2访问内存。 |
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.2.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地址,在上下文切换时不会更改. |
3.2.1.4 VMSAv8-64支持的转换表格式
VMSAv8-64转换表格式支持:
• 多达四个级别的地址查找;
• 转换粒度支持4KB,16KB或64KB;
1. 输入地址
• 如果应用了FEAT_LVA并且使用了64KB转换粒度,则最多为52位;
• 否则,最多48位;
2. 输出地址
• 如果应用了FEAT_LPA并且使用了64KB转换粒度,则最多为52位;
• 否则,最多48位;
3.2.1.5 AArch64 中转换机制/阶段与异常级别之间的关系
3.2.1.6 地址转换阶段控制
对于AArch64控制的每个支持的地址转换阶段:
(1) 系统寄存器 SCTLR_ELx.M 或HCR_EL2.VM 位使能地址转换对应的阶段;
(2) 系统寄存器SCTLR_ELx.EE 位确定转换表查找的字节顺序;
(3) 转换控制寄存器(TCR_ELx )控制地址转换的阶段;
(4) 如果地址转换阶段支持两个VA范围,则该转换阶段将提供:
① 单个TCR_ELx ;
② TTBR_ELx 指定每个VA范围的。 TTBR0_ELx指向地址范围的转换表从0x0000000000000000开始,TTBR1_ELx指向该地址的转换表范围以0xFFFFFFFFFFFFFFFFFF结尾。
否则,一个转换阶段提供一个单独的TCR_ELx和一个单独的TTBR_ELx,它们保存着转换表的地址,在地址转换阶段的第一次查找时必须使用这个地址表。
AArch64转换阶段的使能位和字节序位如下图所示:
3.2.1.7 与MMU操作相关的系统寄存器
3.2.1.8 地址大小配置
1. ID_AA64MMFR0_EL1.PARange字段表示实现的PA大小,如图所示:
2. TCR_ELx.{I} PS字段为该转换阶段最大输出地址大小,如图所示:
该字段的命名如下:
(1) IPS
① 在TCR_EL1中;
② 在包含FEAT_VHE的实现中,当HCR_EL2.E2H的值为1时,在TCR_EL2中;
(2) I=PS
① 其它条件下;
3. TCR_ELx.TxSZ字段为该转换阶段输入地址大小:
-
对于转换阶段可以支持两个VA范围的场景:
TCR_ELx具有两个TxSZ字段,对应于两个VA范围:
① TCR_ELx.T0SZ指定较低的VA范围的大小,使用TTBR0_ELx转换。
② TCR_ELx.T1SZ指定VA上限的大小,并使用TTBR1_ELx进行转换。 -
对于仅支持单个输入地址(IA)范围的转换阶段:
TCR_ELx具有单个T0SZ字段,并且使用TTBR0_ELx转换IA。
3.2.2 内存转换粒度大小
3.2.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 . |
3.2.2.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.2.2.3 三种转换粒度示意图
-
4KB转换粒度示意图
-
16KB转换粒度示意图
-
64KB转换粒度示意图
3.2.2.5 粒度对转换表寻址的影响
粒度 | 最大支持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.2.6 转换表和转换的过程
部分被经常访问的转换表表项被存储在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.2.7 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级联,也就是最大级联24 == 16个translation table级联解析.以达到减少查找level的目的.
- VTTBR_EL2寄存器提供初始Level查找基地址,Stage 2只为EL2服务
- 同Stage 1,Level 1支持1GB的内存block,Level 2支持2MB的内存block
3.2.3 VMSAv8-64转换表格式描述符*
只列出 48-bit OAs的例子(当前主流,能表示的内存大小已足够大256TB),
3.2.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.2.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.2.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.2.4 内存访问控制
主要是对3.3节 转换表描述符中定义数据访问和指令获取的访问权限的字段的进一步解释。
3.2.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.2.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.2.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.2.4.4 指令执行的访问权限(Access permissions for instruction execution)
Execute-never的限制为访问权限设置允许的内存访问提供了额外的控制级别。这些控制包括:
类型 | bit位 | 说明 |
---|---|---|
UXN, Unprivileged execute-never, stage 1 only | 54 | 适用于任何转换体系的stage 1阶段,其中stage 1可以支持两个VA范围。该字段仅适用于EL0执行。值为0表示允许执行。 |
XN, Execute-never | 54 | 此字段适用于转换阶段适用的任何异常级别的执行。值为0表示此控件允许执行: (1) stage 1只支持单个VA范围的任何转换方式的stage 1; (2) 未实现FEAT_XNX的stage 2转换 |
PXN, Privileged execute-never, stage 1 only | 53 | 此字段仅适用于高于EL0的异常级别的执行,值为0表示此控件允许执行: (1)适用于任何转换体系的stage 1阶段,其中stage 1可以支持两个VA范围,对于stage 1只支持单个VA范围的转换体系,stage 1描述符定义了一个PXN字段RES0,这意味着它被硬件忽略 |
XN[1:0], Execute-never, stage 2 only | 54:53 | 在实现FEAT_XNX时进行Stage 2的转换 ,详细见下图 |
-
Stage 1指令访问和执行权限
(1) 表D5-33显示了在使用适用于EL0和更高异常级别的转换机制时,指令执行的stage 1访问权限。
(2) 表D5-34显示了使用仅适用于单个异常级别的转换机制时,指令执行的stage 1访问权限。
仅适用于单个异常级别的AArch64转换方案的访问权限与如下所示的转换表项中的下列字段一致:
(1) AP被视为RES1;
(2) APTable [0]被视为RES0;
(3) PXN被视为RES0;
(4) PXNTable视为RES0; -
Stage 2指令访问和执行权限
对于Secure 或 Non-secure 的EL1&0,当启用EL2 ,stage 2转换表描述符中的XN字段控制执行权限,并且此控制位完全独立于S2AP访问权限:
(1) 如果未实现FEAT_XNX,则stage 2XN字段是一个1位字段,适用于在EL0和EL1处执行;
(2) 当实施FEAT_XNX时,stage 2 XN字段是一个2位字段,可独立控制从EL0执行和从EL1执行; -
指令获取的分层控制
VMSAv8-64转换表格式包括一些机制,通过这些机制,转换表查找的一个级别上的条目可以在后续查找级别上对允许的条目设置限制。
但是,在包含FEAT_HPDS的实现中,当TCR_ELx.HPD {0}字段的值为1或TCR_ELx.HPD1字段的值为1时,由TCR_ELx控制的转换阶段禁用指令获取的分层控制,本小节中的信息不再适用。
这些限制仅适用于同一转换阶段的后续查找级别,并且:
(1) UXNTable或XNTable限制永不执行控制:
① 当XNTable位的值为1时,无论其实际值如何,在所有后续查找级别中XN位均被视为1。
② 当UXNTable位的值为1时,无论其实际值如何,在所有后续查找级别中UXN位均被视为1。
③ 当UXNTable或XNTable位的值为0时,该位无效
(2) 或者一个适用于EL0和更高异常级别的转换机制,PXNTable限制PXN控制;
① 当PXNTable的值为1时,无论该位的实际值如何,在所有后续查找级别中PXN位均被视为1。
② 当PXNTable的值为0时无效
(3) UXNTable,XNTable和PXNTable控件仅提供给阶段1转换。 阶段2转换表描述符中的对应位为RES0。
(4) UXNTable,XNTable或PXNTable的效果适用于转换表中的后续条目,因此其效果可以保留在一个或多个TLB条目中。 因此,对UXNTable,XNTable或PXNTable的更改要求TLB的粗粒度无效,以确保更改的效果对于后续的内存事务可见。 -
防止从writable位置执行
Armv8提供了控制位,当启用了相应的stage 1地址转换时,无论XN或PXN字段的值如何,都将可写内存强制视为execute-never。
(1) 对于适用于EL0和更高异常级别ELx的转换方式,当适用的SCTLR_ELx.WXN字段的值为1时:
① 在地址转换的stage 1中,所有可从EL0写入的区域都被视为stage 1 execute-never at EL0;
② 在地址转换的stage 1中,所有可从ELx写入的区域都被视为stage 1 execute-never at ELx;
(2) 对于仅适用于单个异常级别ELx的转换机制,当适用的SCTLR_ELx.WXN字段的值为1时:
① 在地址转换的stage 1可写的所有区域均视为在stage 1 execute-never。 -
获取安全指令的限制
EL3提供一个安全的指令获取位SCR_EL3.SIF。当该位的值为1,并且执行使用EL3转换机制、Secure EL2转换机制或Secure EL1&0转换机制时,任何试图执行从转换的第一阶段标记为Non-secure 的内存中提取的指令的尝试都会导致权限错误。TLB条目可能反映该位的值,因此该位值的任何更改都需要同步和TLB失效。
在不实现EL3的实现中,该位的有效值为0。
3.2.4.5 访问标志(Access flag)
访问标志指示自相应转换表描述符中的访问标志设置为0以来首次访问内存的page 或section的时间。可由软件或者硬件管理。
3.2.4.6 脏状态(dirty state)
脏状态指示是否修改了内存的page 或section。
脏状态可由硬件管理,如第D5-2614页“脏状态的硬件管理”所述。在硬件中管理脏状态的情况下,使用访问权限位AP[2]和S2AP[1]以及DBM位对脏状态信息进行编码。
3.2.4.7 Block转换条目(Block translation entry)
设置nT位时,如果实现满足level 1或level 2支持,则PE可以:
(1) 使用设置了nT位的转换表条目时,生成转换错误。这样的条目不允许在TLB中缓存。
(2) 保证使用具有nT位的转换表条目不会破坏一致性、顺序保证或单处理器语义,或者在没有nT位的条目转换TLB中缓存的相同地址时无法清除独占监控器。
注意:
使用具有nT位集的转换表条目可能会显著影响转换的性能。
3.2.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转换。
3.3 32位地址转换系统
本节主要简单介绍用于AArch32状态的Armv8 VMSA VMSAv8-32。对于包含所有安全扩展、多处理扩展、大型物理地址扩展和虚拟化扩展的实现,这通常相当于VMSAv7。
由于当前主要处理器内核使用的均是AARCH64的架构,在这里只简单的列举一些重要概念。
3.3.1 AArch32转换机制
3.3.1.1 AArch32转换机制表
当所有实现的异常级别都使用AArch32时,适用以下描述:
| 使用的转换机制 |异常等级 | 说明 |
|--|--|--|:--|
| single PL1&0 stage 1 address translation|VMSAv8-32 without EL2 or EL3 | 这一阶段的地址转换可以在两组转换表之间进行拆分,基址由TTBR0和TTBR1定义,并由TTBCR控制。 |
|Secure PL1&0 stage 1 address translation | VMSAv8-32 with EL3 but without EL2 | 可以在两组转换表之间划分转换的这一阶段,其基地址由TTBR0和TTBR1的 Secure and Non-secure copies定义,并由TTBCR的Secure and Non-secure copies控制。 |
| Non-secure PL1&0 stage 1 address translation| VMSAv8-32 with EL3 but without EL2 | 以在两组转换表之间划分转换的这一阶段,其基地址由TTBR0和TTBR1的 Secure and Non-secure copies定义,并由TTBCR的Secure and Non-secure copies控制。 |
| Non-secure EL2 stage 1 address translation| VMSAv8-32 with EL2 but without EL3 | HTTBR为地址转换的这个阶段定义转换表的基址,由HTCR控制 |
| Non-secure PL1&0 stage 1 address translation| VMSAv8-32 with EL2 but without EL3 | 这一阶段的地址转换可以在两组转换表之间进行拆分,基址由TTBR0和TTBR1的Non-secure copies定义,并由TTBCR的Non-secure实例控制。 |
| Non-secure PL1&0 stage 2 address translation| VMSAv8-32 with EL2 but without EL3 | VTTBR为这一阶段的地址转换定义了转换表的基地址,由VTCR控制 |
| Secure PL1&0 stage 1 address translation| VMSAv8-32 with EL2 and EL3 | 这一阶段的地址转换可以在两组转换表之间进行拆分,基址由TTBR0和TTBR1的Secure copies定义,并由TTBCR的Secure实例控制。 |
| Non-secure EL2 stage 1 address translation| VMSAv8-32 with EL2 and EL3 | HTTBR为这一阶段的地址转换定义了转换表的基地址,由HTCR控制 |
| Non-secure PL1&0 stage 1 address translation | VMSAv8-32 with EL2 and EL3 | 这一阶段的地址转换可以在两组转换表之间进行拆分,基址由TTBR0和TTBR1的Non-secure copies定义,并由TTBCR的Non-secure 实例控制。|
| Non-secure PL1&0 stage 2 address translation| VMSAv8-32 with EL2 and EL3 | VTTBR为这一阶段的地址转换定义了转换表的基地址,由VTCR控制。 |
3.3.1.2 VMSAv8-32转换机大小端的控制
使用的转换机制 | 说明 |
---|---|
PL1&0 stage 1 translations | SCTLR.EE 确定转换表查找的端序 |
Non-secure EL2 stage 1 translations | HSCTLR.EE 确定转换表查找的端序 |
Non-secure PL1&0 stage 2 translations | HSCTLR.EE 确定转换表查找的端序 |
3.3.1.3 VMSAv8-32转换机制中对TLB miss的转换表遍历的控制
TCR中的两个字段中用于控制内存访问所需的转换阶段是否在TLB未命中执行转换表遍历。 这两个字段是:
- PD0和PD1字段,在PE上的使用短描述符转换表格式时。
- EPD0和EPD1字段,在PE上使用长描述符转换表格式时。
3.3.2 VMSAv8-32支持的转换表格式
VMSAv8-32定义了两种备用转换表格式:
1. 短描述符格式(Short-descriptor format)
在转换表中使用32位描述符条目,并提供:
• 最多两个级别的地址查找。
• 32位输入地址。
• 输出地址最多40位。
• 通过使用超级段(16MB粒度)支持超过32位的PA。
• 支持No access, Client, and Manager domains。
2. 长描述符格式(Long-descriptor format)
在转换表中使用64位描述符条目,并提供:
• 最多三个级别的地址查找。
• 用于阶段2转换时,输入地址最多40位。
• 输出地址最多40位。
• 在整个PA范围内分配4KB的分配粒度。
• 不支持domain,所有内存区域均视为Client domain。
• 固定为4KB的表大小,除非被输入地址空间的大小截断。
注意:
• 在特定的安全状态下,PL1&0阶段1转换的转换表可以使用任何一种转换表格式,并且TTBCR.EAE字段指示当前的转换表格式。
• 非安全EL2阶段1转换和非安全PL1&0阶段2转换的转换表必须使用长描述符转换表格式。
3.3.2.1 VMSAv8-32短描述符转换表格式
3.3.2.1.1 短描述符转换表格式总述
-
短描述符转换表格式支持基于内存Sections或pages的内存映射:
(1) Supersections 由16MB的内存块组成。 对Supersections的支持是可选的,除了支持32位以上PA的实现也必须支持Supersections才能提供对整个PA空间的访问。
(2) Sections 由1MB的内存块组成。
(3) Large pages 由64KB内存块组成。
(4) Small pages 面由4KB的内存块组成。
注意:
(1) 短描述符格式转换表的VMSAv8-32实现是否支持超级段,已在IMPLEMENTATION DEFINED中定义。
(2) EL2转换机制不能使用短描述符转换表格式。 -
使用短描述符转换表格式时,两个Level的转换表保存在内存中:
Level 1 table
包含基址和
(1) Section和Supersection的转换属性。
(2) 转换属性和指向Large page 或 a Small page的2级表的指针。
Level 2 table
保存包含小页或大页的基址和转换属性的第2级描述符。对于短描述符格式,二级表可以称为转换表。级别2的表需要1KB的内存。 -
使用VMSAv8-32短描述符格式转换表进行地址转换的通用视图如下:
3.3.2.1.2 VMSAv8-32短描述符转换表格式
- 短描述符转换表level 1描述符格式
描述符位[1:0]标识描述符类型。这些比特的编码是:
描述符类型 | bit[1:0] | 说明 |
---|---|---|
Invalid entry | 0b00 | 关联的VA未映射,任何访问它的尝试都会产生转换错误 |
Translation table | 0b01 | 描述符给出了一个二级转换表的地址,该转换表指定了关联的1MByte VA范围的映射 |
Section or Supersection | 0b10 | 描述符给出了Section 或Supersection的基址,位[18]决定条目是描述一个Section 还是Supersection。这种编码还将PXN字段定义为0 |
Section or Supersection(if the implementation supports the PXN attribute) | 0b11 | 与0b10相同,除了将PXN字段定义为1。 |
- 短描述符转换表level 2描述符格式
描述符位[1:0]标识描述符类型。这些比特的编码是:
描述符类型 | bit[1:0] | 说明 |
---|---|---|
Invalid entry | 0b00 | 关联的VA未映射,当试图访问它时会产生转换错误 |
Large page | 0b01 | 描述符给出了Large page的基址和属性 |
Small page | 0b1x | 描述符给出Small page的基址和属性。在这种描述符格式中,描述符的[0]位是XN字段。 |
- 短描述符格式转换表的附加要求
当使用短描述符转换表格式的Supersection 或 Large page 描述符时,定义Supersection 或Large page 描述符地址的输入地址字段与表地址字段重叠。在每种情况下,重叠的大小都是4位。以下图表显示了这些重叠部分:
(1) Supersection
(2) Large page
考虑到在2级转换表中使用 Large page 描述符的情况,这种重叠意味着对于任何特定的 Large page ,2级转换表条目的后四位可能取0b0000到0b1111之间的任何值。 因此,这16个索引值中的每一个都必须指向同一描述符的单独副本。
这意味着每个Supersection 或 Large page 描述符必须:
(1) 首先出现在十六个word的边界上。
(1) 在16个连续的存储位置中重复(连续16个条目的内容一样)。
3.3.2.1.3 VMSAv8-32短描述符转换表格式描述符中的内存属性
字段 | 说明 |
---|---|
TEX[2:0](Type extension), C (Cacheable), B (Bufferable) | 内存区域属性字段,主要用来描述内存type、Cacheable、Bufferable |
XN(Execute-never | executor-never 控制是否可以从内存区域执行指令 |
PXN(Privileged execute-never) | 当在转换表的描述符中将此字段设置为1时,表示在相应转换表中描述的所有内存页均不执行特权访问 |
NS(Non-secure) | 对于从安全状态访问内存,指定输出地址是在安全地址映射中还是在非安全地址映射中: (1) NS == 0 访问安全PA空间 (2) NS == 1 访问非安全PA空间 。 对于不安全的转换机制,以及从不安全内存中获取的转换表描述符,对应的位是RES0,并被PE忽略。无论位的值是多少,访问的都是不安全的内存 在短描述符转换表格式中,仅在1级转换表中定义了NS位。 这意味着,在转换表的1级描述符中,NS位为该表描述的所有Large pages和Small pages定义了安全或非安全的PA映射。 |
Domain | (1) Supersection条目中不存在此字段。 Supersections描述的内存在域0中。 (2) 该位在2级描述符中不存在。 转换表的1级描述符中“域”字段的值适用于相应表中的所有条目 |
An IMPLEMENTATION DEFINED bit(Dirty Bit Modifier) | 该位在2级描述符中不存在 |
AP[2], AP[1:0](Access flag) | 数据访问权限位,在 translation table的描述符中不存在 |
S bit(Guarded Page) | Shareable属性 |
nG(not global) | 非全局bit位。如果使用此描述符的查找被缓存在TLB中,确定TLB条目是应用于全局ASID值,还是仅应用于当前ASID值 |
Bit[18], when bits[1:0] indicate a Section or Supersection descriptor | (1) 0 Section 描述符。 (2) 1 Supersection 描述符 |
3.3.2.1.4 在TTBR0和TTBR1的使用
可以为PL1&0第1阶段的每个转换定义两组转换表,并且TTBR0和TTBR1保留两组表的基址。 当使用短描述符转换表格式时,TTBCR.N的值指示输入VA的最高有效位的数量,这些值确定TTBR0或TTBR1是否持有所需的转换表基地址,如下所示:
- 如果N == 0,则使用TTBR0。 将TTBCR.N设置为零将禁用第二组转换表的使用。
- 如果N> 0,则:
(1)如果输入VA的位[31:32-N]全部为零,则使用TTBR0。
(2)否则使用TTBR1
下图说明N的值如何确定使用TTBR1转换的最低地址,以及TTBR0处理的第一级转换表的大小:
下图显示TTBCR.N的值如何控制使用TTBR0转换的VA和使用TTBR1转换的VA之间的边界。:
3.3.2.2 VMSAv8-32长描述符转换表格式
3.3.2.2.1 长描述符转换表格式总述
VMSAv8-32长描述符转换表格式支持在整个输入地址范围内以4KB的粒度将内存属性分配给内存页。它还支持将内存属性分配给内存块,其中一个块可以是2MB或1GB。
-
长描述符转换表格式可用于:
(1) Non-secure EL2 stage 1 translation;
(2) Non-secure PL1&0 stage 2 translation;
(3) Secure and Non-secure PL1&0 translations; -
使用VMSAv8-32长描述符格式转换表进行地址转换的通用视图如下:
3.3.2.2.2 VMSAv8-32短描述符转换表格式
- 长描述符level 1和level 2描述符格式
描述符位[1:0]标识描述符类型。这些比特的编码是:
描述符类型 | bit[1] | bit[0] | 说明 |
---|---|---|---|
Invalid | - | 0 | 无效描述符,任何访问该地址的尝试都会生成转换错误 |
Block | 0 | 1 | 提供内存块的基地址和该内存区域的属性 |
Table | 1 | 1 | 提供下一级转换表的地址,对于阶段1的转换,提供该转换的一些属性 |
- 长描述符level 3描述符格式
描述符位[1:0]标识描述符类型。这些比特的编码是:
描述符类型 | bit[1] | bit[0] | 说明 |
---|---|---|---|
Invalid | - | 0 | 无效描述符,任何访问该地址的尝试都会生成转换错误 |
Reserved, invalid | 0 | 1 | 与位[0]设置为0的编码行为相同 |
Page | 1 | 1 | 给出一个4KB内存页的地址和属性 |
3.3.2.2.3 VMSAv8-32长描述符转换表格式描述符中的内存属性
- VMSAv8-32长描述符stage1 Table 描述符
stage1 转换的Table 描述符中,描述符的位[63:59]定义了下一级转换表访问的属性:
字段 | bit位 | 说明 |
---|---|---|
NSTable(Non-secure) | [63] | 安全模式标志位: (1) NSTable == 0 :定义的表地址在安全PA空间中 (2) NSTable == 1 :定义的表地址在非安全PA空间中 |
APTable(Access permissions) | [62:61] | 后续查找级别的访问权限限制 APTable[0] is RES0:in the Non-secure EL2 stage 1 translation |
XNTable (Execute-never ) | [60] | 对后续查找级别的执行(XN)权限限制 |
PXNTable | [59] | 对后续查找级别的PXN限制,P(privileged)是指特权 |
- VMSAv8-32长描述符stage1 Block和Page描述符
在Block描述符和Page描述符中,内存属性被分为一个upper block和一个 lower block,如图所示:
字段 | bit位 | 说明 |
---|---|---|
PBHA(Page-based Hardware Attributes) | [62:59] | 基于页面的硬件属性位。当没有实现FEAT_HPDS2(Translation table page-based hardware attributes)时,这些位被忽略 |
XN(Execute-never) | [54] | executor-never 控制是否可以从内存区域执行指令 |
PXN(Privileged execute-never) | [53] | 特权execute-never bit位 只有在转换stage1能够支持两个VA范围时,该字段才有效。stage1只能支持一个VA范围时值为RES0 |
Contiguous | [52] | 表示相邻的转换表条目指向具有相同权限和属性的连续输出地址范围 |
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 |
- VMSAv8-32长描述符stage2 Block和Page描述符
字段 | bit位 | 说明 |
---|---|---|
PBHA(Page-based Hardware Attributes) | [62:60] | 基于页面的硬件属性位。当没有实现FEAT_HPDS2(Translation table page-based hardware attributes)时,这些位被忽略 |
PBHA[0] (Page-based Hardware Attributes) | [59] | 基于页面的硬件属性位。当没有实现FEAT_HPDS2(Translation table page-based hardware attributes)时,这些位被忽略 |
XN (Execute-never) | [54:53] | executor-never 控制是否可以从内存区域执行指令 |
Contiguous | [52] | 表示相邻的转换表条目指向具有相同权限和属性的连续输出地址范围 |
nG(not global) | [11] | 非全局bit位。如果使用此描述符的查找被缓存在TLB中,确定TLB条目是应用于全局ASID值,还是仅应用于当前ASID值 |
AF(Access flag) | [10] | 访问标志指示自从对应应转换表描述符中的访问标志设置为0后,何时第一次访问内存的页或段 |
SH(Shareability field) | [9:8] | 用来指示一个内存位置对于一些处理器是否是可共享的。共享意味着需要硬件保证一个内存位置中的内容对一定范围内可访问该位置的多个处理器是一致。Shareability属性有Non-shareable、InnerShareable和Outer Shareable三个选项 |
S2AP | [7:6] | stage 2 Access flag |
MemAttr | [4:2] | stage2内存属性索引字段,用于指示内存的类型和缓存性 |
3.3.2.2.4 在TTBR0和TTBR1之间选择,VMSAv8-32长描述符转换表格式
可以为PL1&0 stage1阶段的每个转换定义两组转换表,并且TTBR0和TTBR1保留两组表的基址。 当长描述符转换表格式在定义TTBR0和TTBR1之间的边界时提供了更大的灵活性。当启用PL1&0 stage1地址转换时,TTBR0总是被使用。如果TTBR1也被使用,则:
(1)TTBR1用于输入地址范围的顶部;
(2)TBR0用于输入地址范围的底部部分;
TTBCR.T0SZ 和 TTBCR.T1SZ size字段控制TTBR0和TTBR1的使用,如表G5-2所示:
3.3.2.3 内存访问控制
3.3.2.3.1 数据访问权限
转换表描述符中的访问权限位控制对相应内存区域的访问。该控制位的详细信息取决于转换表的格式,如下所示:
类型 | 说明 |
---|---|
Short-descriptor format | 这种格式支持两个选项来定义访问权限: (1) 3比特,AP[2:0]定义访问权限(Arm 不推荐) ; (2) 2比特,AP[2:1]定义访问权限,AP[0]可以作为访问标志。 SCTLR.AFE 选择访问权限选项。 将该位置1,以启用访问标志,同时选择使用AP [2:1]定义访问权限 |
Long-descriptor format | AP [2:1]控制访问权限,描述符提供一个AF位用作访问标志。 这意味着VMSAv8-32的行为就像SCTLR.AFE的值为1一样(同短描述符(2)的格式 ) |
-
AP[2:1] access permissions model
-
长描述符格式中的分级控制访问权限
注意:
(1) 这些限制仅适用于同一转换stage的后续查找级别;
(2) 长描述符格式仅为stage 1的转换提供了APTable[1:0] 控制,对应的位在stage 2转换表描述符中默认为SBZ;
-
AP[2:0] access permissions control, Short-descriptor format only
这个不讲,ARM手册明确说明,不推荐这种用法。
3.3.2.3.2 指令执行的访问权限
Execute-never的限制为访问权限设置允许的内存访问提供了额外的控制级别。这些控制包括:
类型 | bit位 | 说明 |
---|---|---|
XN, Execute-never | 54 | 适用于转换阶段适用的任何异常级别的执行。值为0表示此控件允许执行。 |
PXN, Privileged execute-never, stage 1 only | 53 | 仅适用于高于EL0的异常级别的执行。值为0表示此控件允许执行 |
XN[1:0], Execute-never, stage 2 only | 54:53 | 00 The stage 2 control permits execution at EL1 and EL0 if read access is permitted; 01 The stage 2 control does not permit execution at EL1, but permits execution at EL0 if read access is permitted; 10 The stage 2 control does not permit execution at EL1 or at EL0; 11 The stage 2 control permits execution at EL1 if read access is permitted, but does not permit execution at EL0; |
-
长描述符格式中指令获取的分级控制
XNTable 对 XN 的限制
(1) XNTable设置为1时,无论XN字段的实际值是多少,在随后的所有级别的查找中,XN字段都被视为1。
(2) 当XNTable设置为0时,不生效。
PXNTable 对 PXN 的限制:
(1) 当PXNTable设置为1时,PXN字段在随后的所有级别的查找中都被视为1,而不管该字段的实际值是多少。
(2) 当PXNTable设置为0时,它没有作用。 -
防止从writable位置执行
Armv8提供了控制位,当启用了相应的stage 1地址转换时,无论XN或PXN字段的值如何,都将可写存储器强制视为XN或PXN。当转换阶段由使用AArch32的异常级别控制时:
(1) 对于PL1&0 stage 1 translations,当SCTLR.WXN设置为1时,在地址转换的stage 1可写的所有区域均被视为XN。
(2) 对于PL1&0 stage 1 translations,当SCTLR.UWXN设置为1时,如果指令访存访问EL0上执行的软件可以写入的区域,则将其视为访问PXN区域。
(3) 对于非安全EL2第1阶段转换,当HSCTLR.WXN设置为1时,在地址转换的stage 1可写的所有区域均被视为XN。 -
获取安全指令的限制
EL3提供了一个安全的指令获取位,SCR.SIF。当这个位为1时,任何试图在安全状态下执行从非安全物理内存获取的指令都会导致权限错误。与所有权限错误检查一样,当使用短描述符格式转换表时,检查只适用于Client domains。
3.3.2.3.3 域(仅支持短描述符格式)
域是内存区域的集合。 短描述符转换表格式支持16个域,并且需要定义转换表的软件才能将每个VMSAv8-32内存区域分配给一个域。 使用短描述符格式时:
- translation tables和Sections的Level 1转换表条目包括一个域字段。
- Supersections的转换表条目不包含域字段。 短描述符格式将Supersections定义为域0。
- Level 2转换表条目从父级别Level 1转换表描述符继承域设置。
- 每个TLB条目都包含一个域字段。
域字段指定条目所在的16个域中的哪一个,DACR(Domain Access Control Register)中的两位字段定义了每个域是否允许访问。 每个域的可能设置是:
类型 | 说明 |
---|---|
No access | 任何使用转换表描述符的访问都会生成一个域错误 |
Clients | 在使用翻译表描述符的访问中,会检查访问权限属性。因此,访问可能会产生权限错误 |
access | 对于使用翻译表描述符的访问,不检查访问权限属性。因此,访问不能产生权限错误 |
3.3.2.3.4 访问标志(Access flag)
访问标志指示自相应转换表描述符中的访问标志设置为0以来首次访问内存的page 或section的时间。
armv8.0要求软件管理访问标志。这意味着,当试图将访问标志值为0的转换表描述符条目读入TLB时,就会产生访问标志错误。访问标记机制希望在发生访问标记错误时,软件将导致该错误的转换表条目中的访问标记重置为1。 这样可以防止在下次访问存储位置时发生故障。 将访问标志设置为0的条目永远不会保存在TLB中,这意味着在设置该标志之后,软件不必从TLB中清除该条目。
3.3.2.4 内存区域属性
3.3.2.4.1 stage 1转换的内存区域属性概述
1.内存类型和属性的描述方式
对内存类型和属性的描述有如下两种方式:
- 直接按转换表描述符中的位。
- 通过表描述符中的位引用的寄存器间接进行。 这称为重新映射内存类型和属性描述。
(1) 短描述符翻译表格式可以使用由SCTLR.TRE位选择的以下两种方法之一
TRE值 | 功能 | 说明 |
---|---|---|
TRE == 0 | Remap disabled | 转换表描述符中的TEX[2:0], C和B位定义了内存区域属性 |
TRE == 1 | Remap enabled | 转换表描述符中的TEX[0]、C和B位是定义内存区域属性的remap寄存器的索引位: (1) 主区域重映射寄存器PRRR; (2) Normal Memory 重映射寄存器NMRR; |
(2) 长描述符翻译表格式始终使用重映射(remapping)。 这意味着,当TTBCR.EAE的值为1时,启用长描述符转换表格式的使用,SCTLR.TRE为RES1。
2.Shareability
(1) 在短描述符转换表格式中,转换表描述符中的S位用于确定区域的可共享性。 如何解释S位取决于TEX是否使能重新映射;
(2) 在长描述符转换表格式中,转换表描述符中的SH [1:0]字段对区域的可共享性进行编码。
3.3.2.4.2 短描述符格式的内存区域属性 ——没有TEX重映射
当使用短描述符翻译表格式时,当SCTLR.TRE的值为0时,将禁用TEX(Type extension) 重映射。
表G5-12显示了禁用TEX重映射时的C,B和TEX [2:0]编码。 在“Page Shareability”列中,S bit的指示转换表描述符中的S位:
- Cacheability attributes, without TEX remap
(1) 当TEX [2]的值为0时,相同的Cacheability属性适用于Inner Cacheable 和 Outer Cacheable内存区域,并且{TEX [1:0],C,B}值标识此属性,如表G5-12所示。
(2) 当TEX [2]的值为1时,转换表条目描述的内存是cacheable的,其余的编码定义Inner Cacheable 和 Outer Cacheable属性:
① TEX [1:0] 定义Outer Cacheability属性;
② C,B定义Inner Cacheable属性;
转换表的表项的Outer和Inner Cacheability属性使用相同的编码,如表G5-13所示
- Shareability and the S bit, without TEX remap
短描述符格式转换表条目包含一个S位。 该bit:
(1) 如果该条目引用任何类型的Device类型内存,或者是Normal 类型内存是 InnerNon-cacheable和Outer Non-cacheable的,则将被忽略。
(2) 对于不是Inner Non-cacheable, Outer Non-cacheable的Normal类型内存,确定内存区域是Outer Shareable or Non-shareable:
① S == 0 Normal 类型内存区域不可共享。
② S == 1 Normal 类型内存区域是外部共享的。
如果没有TEX重新映射,则内部共享内存和外部共享内存之间没有区别,这意味着S位确定区域是不可共享的还是外部共享的。
3.3.2.4.3 短描述符格式的内存区域属性 ——有TEX重映射
-
当使用短描述符翻译表格式时,当SCTLR.TRE的值为1时,将启用TEX重映射。在此配置中:
(1) 定义转换表的软件必须对PRRR和NMRR进行编程,以定义七个可能的内存属性。
(2) 转换表描述符的TEX [0],C和B位通过索引PRRR和NMRR定义存储区属性。
(3) 硬件不使用TEX [2:1]。 -
启用TEX重映射后:
(1) 对于TEX [0],C和B位的八种可能组合中的七种,PRRR和NMRR中的字段定义了区域属性,如本节所述。
(2) TEX [0],C和B位的第八种组合的含义为IMPLEMENTATION DEFINED。
(3) 如果TEX [0],C和B位确定该区域是Device类型内存,或者是Normal Inner Non-cacheable, Outer Non-cacheable,则该区域是Outer Shareable的。否则,可共享性为由以下各项的组合确定:
① 转换表描述符中的S位。
② PRRR.NS0或PRRR.NS1位的值。
① 适当的PRRR.NOSn位的值,如表G5-14所示。 -
对于转换表条目中TEX [0],C和B位的每种可能编码,表G5-14显示了PRRR和NMRR寄存器的哪些字段描述了存储区属性:
-
Shareability, with TEX remap
如表G5-14的“Memory type”列中所示,区域的内存类型提供了对该区域Shareability的第一级控制:
(1) 如果内存是任何Device类型内存,则该区域为Outer Shareable,并且该表的转换表描述符和PRRR中的任何Shareability属性都将被忽略。这也适用于NMRR属性标识为Inner Non-cacheable, Outer Non-cacheable的Normal 类型内存区域,
(2) 如果使用短描述符转换表格式,则使用转换表描述符中S位的值决定PRRR.{NS1. NS0}中的一个索引来确定区域的可共享性。表G5-15显示了转换表S位如何索引到PRRR:
对于非Inner Non-cacheable, Outer Non-cacheable的Normal 类型内存区域,PRRR寄存器的某些的位决定区域是否Non-shareable,具体如下:
(1) PRRR.NSn= =0 : Non-shareable.
PRRR.{NOS7:NOS0} are ignored.
(2) PRRR.NSn= =1 : PRRR.NOSm , 用于标识区域是 Inner Shareable 还是 Outer Shareable的:
① PRRR.NOSm= =0 Region is Outer Shareable.
② PRRR.NOSm= =1 Region is Inner Shareable
3.3.2.4.4 长描述符格式的内存区域属性 ——默认TEX重映射
当PE使用VMSAv8-32长描述符转换表格式时,stage1转换的block 或 page转换表描述符中的AttrIndx [2:0]字段指示相应MAIR寄存器中的8位字段,指定相应内存区域的属性,如下所示:
(1) AttrIndx [2]指示要使用的MAIR寄存器:
①AttrIndx [2] = = 0使用MAIR0。
②AttrIndx [2] = = 1使用MAIR1。
(2) AttrIndx [2:0]表示所需的Attr字段Attrn,其中n = AttrIndx [2:0]。
每个AttrIndx字段都为相应的内存区域定义:
(1) 内存类型,Normal 或 Device memory的类型。
(2) 对于Normal 类型内存:
① Inner cacheability 和 Outer cacheability属性,每个属性都是Non-cacheable,Write-Through Cacheable, Write-Back Cacheable之一。
② 对于Write-Through Cacheable 和 Write-Back Cacheable 区域,ead-Allocate 和Write-Allocate策略提示,每个提示都是allocate 或No allocate的。
-
Shareability, Long-descriptor format
当PE使用Long-descriptor转换表格式时,如果该区域的MAIR条目将其标识为Normal,则block 或 page转换表描述符中的SH [1:0]字段将指定相应内存区域的Shareability属性,非 Non-cacheable 和Outer Non-cacheable。 表G5-16显示此字段的编码。
此外,对于任何类型的Device 内存,以及对于Normal Inner Non-cacheable, Outer Non-cacheable内存,转换表描述符的SH [1:0]字段的值都将被忽略。 -
Contiguous bit 位
长描述符转换表格式描述符包含一个连续位。将该位设置为1表示16个相邻的转换表条目指向连续的输出地址范围。这16个条目必须在转换表中对齐,以便它们输入地址的高五位(在转换表中索引位置)是相同的。例如,要将此位用于3级转换表中的16个条目的块,则16个条目的输入地址的位[20:16]必须相同。
连续的输出地址范围必须与同一转换表级别上的16个转换表条目的大小对齐。
3.3.2.4.4 Non-secure EL2内存属性
在EL2上执行的软件控制着两组转换表,它们都使用长描述符转换表格式。分别是:
- 控制Non-secure EL2 stage 1转换的转换表,针对VA映射到PA。当EL2使用AArch32时,它们由HTTBR和HTCR指示和控制。这些转换具有与任何其他stage 1转换完全相同的存储区属性。
- 控制Non-secure PL1&0 stage 2转换的转换表。这些映射将stage 1转换中的IPA映射到PA上,并加以指示,当EL2使用AArch32时,它们由VTTBR和VTCR控制。虚拟化转换表中的描述符定义了2级内存区域属性,这些属性与stage 1转换中定义的属性结合在一起。
注意
在虚拟化应用的场景中,hypervisor可能会有用:
- 降低区域的允许缓存性。
- 增加所需的区域共享性。
来自stage 1和stage 2转换的属性的组合支持这两个选项。
-
在用于内存区域和页面的stage 2转换表描述符中,MemAttr [3:0]和SH [1:0]字段描述了stage 2内存区域属性:
(1) stage 2 SH [1:0]字段的定义与stage 1转换的相同字段相同。
(2) MemAttr [3:2]给出了内存类型的顶层定义,以及Normal类型内存的cacheability,如表G5-17所示:
-
MemAttr[1:0]的编码取决于MemAttr[3:2]所指示的内存类型
(1) 当MemAttr[3:2]==0b00表示Device内存的一种类型时,MemAttr [1:0)编码如表G5-18所示
(2) 当MemAttr[3:2]!=0b00表示Normal内存的一种类型时,MemAttr [1:0)编码如表G5-19所示
-
组合内存类型属性
:表G5-20显示了stage 1和stage 2的内存类型分配是如何组合的:
-
组合Cacheability属性
对于Normal内存区域,表G5-21显示了如何组合stage 1和stage 2的Cacheability。 此组合分别适用于nner Cacheability 和Outer Cacheability属性,只有Normal内存具有可缓存性属性。
-
组合Shareability属性
在以下情况下,无论在转换的任何阶段进行任何Shareability分配,都将内存区域视为Outer Shareable:
(1) 合成内存类型属性(在表G5-20 的组合内存类型属性中描述)是任何类型的Device内存。
(2) 组合内存类型属性是Normal内存,并且在组合Cacheability属性是 Inner Non-cacheable Outer Non-cacheable。
对于组合内存类型属性为Normal而不是Inner Non-cacheable Outer Non-cacheable的内存区域,表G5-22显示了如何组合stage 1和stage 2的Shareability分配:
本文来自博客园,作者:BSP-路人甲,转载请注明原文链接:https://www.cnblogs.com/jianhua1992/p/16852783.html,并保留此段声明,否则保留追究法律责任的权利。