时间轴
时间轴
2025-10-26
init
本文介绍了ARM架构中TLB(Translation Lookaside Buffer)的基本概念、工作原理及其在ARMv8-A处理器中的实现。文章首先说明了TLB作为页表转换结果缓存的作用,以及页表基地址寄存器TTBR0_EL1和TTBR1_EL1的寻址规则,并介绍了TLB的映射方式(全相连和组相连)及Cortex-A72的两级TLB设计。随后,文章讨论了TLB的重名与同名问题,重点阐述了ASID(地址空间标识符)机制如何通过区分不同进程的TLB条目来解决进程切换时的同名问题,并说明了ASID的存储、宽度及Linux内核中的管理方式(包括位图分配和溢出处理)。此外,文章还介绍了页表项中nG属性用于标识全局或进程特有的TLB条目,以及连续块条目功能如何提高TLB缓存效率。最后,文章总结了TLBI指令的用途和格式,用于在操作系统修改映射后使陈旧的TLB条目失效。整体内容涵盖了TLB的关键技术
参考文档:
ARMv8.6 芯片手册与TLB相关内容
D5.9章 Translation Lookaside Buffers(TLBs)
D5.10章 TLB maintenance requirements and the TLB maintenance instructions
TLB背景知识

- TLB是cache的一种
- TLB的表项:记录了最新使用的VA到PA的转换结果
- 页表基地址在 Translation Table Base Register(TTBR0_EL1 和 TTBR1_EL1)中指定。当 VA 的高位全为 0 时,使用 TTBR0 所指向的页表进行遍历;当 VA 的高位全为 1 时,使用 TTBR1。TLB 本身没有基地址,它是用于缓存页表转换结果的硬件单元。
- EL2 和 EL3 只有 TTBR0,没有 TTBR1。默认情况下(TCR_ELx.T0SZ = 16)可寻址范围为 0x0 到 0x0000FFFF_FFFFFFFF,但该范围可通过 T0SZ 字段调整。

- TLB 支持全相连(fully-associative)和组相连(set-associative)等映射方式。
- Cortex-A72 采用两级 TLB 设计,类似 2 级 cache 的设计思路。
- L1 instruction and data TLBs(全相连)
- 48-entry fully-associative L1 I-TLB
- 32-entry fully-associative L1 D-TLB
- L2 unified TLB:4-way set-associative of 1024-entry L2 TLB(组相连)
- L1 instruction and data TLBs(全相连)

每个 TLB 条目通常不仅包含物理地址和虚拟地址,还包含诸如内存类型、缓存策略、访问权限、地址空间 ID
(ASID)和虚拟机 ID(VMID)等属性

TLB的重名(别名)问题

虽然 VP1 和 VP2 在 TLB 里缓存了两个不同的 TLB entry,但是 TLB entry 里的 PFN 都指向同一个物理页(Phys Page),所以不会产生别名问题
TLB的同名问题

进程 A 切换到进程 B 时,旧进程使用的 TLB 对新进程来说是无用数据,并且可能产生同名问题。如果直接在进程切换时 invalidate TLB,那么性能上会有较大损失。解决方法就是使用 ASID(Address Space Identifier) 技术
ASID(Address Space Identifier)
全局类型的TLB:内核空间是所有进程共享的空间
进程独有类型的TLB:用户地址空间是每个进程独立的地址空间
ASID机制用来实现进程独有类型的TLB
ARMv8 的 ASID 存储在 TTBR0_EL1 或者 TTBR1_EL1 中,其中 TCR 寄存器的 A1 域可以选择使用哪个 TTBR 的 ASID
ASID支持8位或者16位
- 8位宽的ASID,最多支持256个ID
- 16位宽的ASID,支持65536个ID


TCR_EL1 中定义:

TLB 可以识别哪个 TLB entry 属于哪个进程(通过 ASID 字段),这是解决 TLB 同名问题的核心思想。这样进程切换时只需刷掉被切换进程的 TLB entry,而其他进程的 TLB entry 可以保留
操作系统常使用位图的方式管理ASID,一般不会用进程的PID

此外,ARMv8-A 架构提供线程 ID 寄存器供操作系统软件使用。这些寄存器没有硬件意义,通常由线程库作为每个线程数据的基本指针使用。这通常被称为线程本地存储(TLS)。例如,pthreads 库使用这一功能,包括以下寄存器:
- 用户读写线程 ID 寄存器(TPIDR_EL0)。
- 用户只读线程 ID 寄存器(TPIDRRO_EL0)。
- 线程 ID 寄存器,仅限特权访问(TPIDR_EL1)
Linux内核里的ASID
Linux 内核早期版本(ARM64 架构)为每个进程分配两个 ASID,即奇、偶数组成一对
- 当进程运行在用户态时,使用奇数 ASID 来查询 TLB
- 当程序陷入内核态运行时,使用偶数 ASID 来查询 TLB
为每个进程分配两个 ASID 主要是为了解决熔断(Meltdown)漏洞问题,通过隔离用户态和内核态的 TLB 条目来防止侧信道攻击
注:较新的 Linux 内核已采用基于时间戳的 ASID 回收策略(ASID 版本号机制),不再使用奇偶配对方式。
硬件的ASID的分配通过位图来分配和管理
进程切换的时候,需要把进程持有的硬件 ASID 写入到 TTBR0_EL1 寄存器里(用户空间使用 TTBR0_EL1 的 ASID 字段)
当系统中所有的硬件ASID加起来超过硬件最大值时会发生溢出,需要刷新全部TLB,然后重新分配硬件ASID

页表项中的nG属性

第11位nG:
1:表示这个页面对应的TLB页表项是进程特有的
0:表示是使用全局的TLB
TLB缓存一个块
ARMv8-A 架构提供了一个称为连续块条目的功能,以有效地使用 TLB 空间。
映射表块条目每个都包含一个连续的位。当设置时,该位向 TLB 发出信号,它可以缓存一个涵盖多个块的映射的单一条目。一个查找可以索引到一个连续块所覆盖的地址范围的任何地方。因此,TLB 可以为定义的地址范围缓存一个条目,使得在 TLB 中存储更大范围的虚拟地址成为可能。
要使用一个连续的位,连续的块必须是相邻的,也就是说它们必须对应于一个连续的虚拟地址范围。它们必须从一个对齐的边界开始,具有一致的属性,并指向同一级别转换的连续输出地址范围。
TLBI指令
如果操作系统修改了可能已缓存在 TLB 中的映射条目,那么操作系统就有责任使这些陈旧的 TLB 条目失效,需要使用TLBI指令
- ARMv8提供了TLBI指令
- 指令格式:
1 | TLBI <type><level>{IS} {,Xt} |
- Type:
- ALL 整个TLB
- VMALL 所有的TLB entry(stage 1, for current guest OS)
- VMALLS12 所有的TLB entry(stage 1&2 for current guest OS)
- ASID 和 ASID 匹配的 TLBI 指令,Xt 指定 ASID
- VA 虚拟地址指定的 TLBI 指令,Xt 指定虚拟地址以及 ASID
- VAA 虚拟地址指定的 TLBI 指令,Xt 指定虚拟地址但是不包括 ASID
- Level:En=异常等级(n可以是3,2,or 1)
- IS:表示inner share
- Xt:由虚拟地址和 ASID 组成的参数
- Bit[63:48]:ASID
- Bit[47:44]:TTL,用于指明使哪一级页表缓存的地址无效。若为 0,表示需要使所有级别的页表缓存无效(一般都设置为 0)
- Bit[43:0]:虚拟地址的 Bit[55:12](即 VA[55:12])

例子:修改页表后对TLB进行刷新
12345 | // Writes to Translation TablesDSB ISHST // ensure write has completedTLBI ALLE1 // invalidate all TLB entriesDSB ISH // ensure completion of TLB invalidationISB // synchronize context so no old translations are used |
执行场景:你修改了页表映射(如修改虚拟地址到物理地址的映射),CPU 仍可能用旧 TLB 翻译缓存,所以:
- 必须先确保页表写入完成 →
DSB ISHST - 使旧 TLB 失效 →
TLBI ALLE1 - 确保失效动作真正完成 →
DSB ISH - 刷新 CPU 指令执行上下文 →
ISB
相关寄存器
TCR_EL1
TCR_EL1 控制 EL1 和 EL0 的其他内存管理功能。



| 字段 | 位范围 | 含义 | 用于 |
|---|---|---|---|
| T0SZ | [5:0] | 控制 TTBR0 的虚拟地址空间大小 | 用户空间或低地址映射 |
| TG0 | [15:14] | TTBR0 页大小(Granule Size) | 4KB/16KB/64KB 页 |
| T1SZ | [21:16] | 控制 TTBR1 的虚拟地址空间大小 | 内核空间或高地址映射 |
| TG1 | [31:30] | TTBR1 页大小(Granule Size) | 4KB/16KB/64KB 页 |
| IPA size | [34:32] | 控制中间物理地址宽度 (Intermediate Physical Address Size) | 用于虚拟化或物理地址上限设置 |
