来源 :ARM Architecture Reference Manual, D8.6.5 & D8.6.7
适用场景:虚拟化环境下,Hypervisor 通过 Stage 2 页表对 Guest 物理地址做二次翻译,此时内存属性由两级页表共同决定。
1. 背景:两级地址翻译
在 ARM 虚拟化扩展中,地址翻译分为两个阶段:
| 阶段 | 作用 | 控制寄存器 |
|---|---|---|
| Stage 1 | VA → IPA(虚拟地址 → 中间物理地址) | VM 的页表(由 Guest OS 管理) |
| Stage 2 | IPA → PA(中间物理地址 → 物理地址) | Hypervisor 配置的页表(VTCR_EL2 / VTTBR_EL2) |
当程序访问一个虚拟地址时,MMU 会依次经过两级页表翻译,最终得到物理地址。这两级页表各自携带了内存属性(类型、缓存策略、可共享性等),最终生效的属性由两级属性合并(Combine) 而来,而非简单取其一。
前提 :以下规则仅适用于
HCR_EL2.FWB == 0的情况。当 FWB(Force Write-Back)置位时,行为会有所不同。
2. 内存类型(Memory Type)合并
Stage 1 和 Stage 2 对内存类型的约束不同,合并规则遵循保守策略:哪级更严格,就取哪级。
2.1 合并规则总览
| 条件(任一级满足) | 最终内存类型 |
|---|---|
| 任意 Device 类型 | 对应的 Device 类型 |
| 任意 Device-nGnRx 类型 | Device-nGnRx |
| 任意 Device-nGnRnE 类型 | Device-nGnRnE |
具体对应关系:
Rule 1: 任一级 → Device → 结果: Device(取最严格 Device 子类型)
Rule 2: 任一级 → Device-nGxx → 结果: Device-nGxx
Rule 3: 任一级 → Device-nGnRx → 结果: Device-nGnRx
Rule 4: 任一级 → Device-nGnRnE → 结果: Device-nGnRnE
2.2 理解 Device 属性的层级
Device 属性从宽到严有以下层级:
Device-nGnRnE (最严格:No Gathering, No Reordering, No Early Write Ack)
↑
Device-nGnRE (允许 Early Write Ack)
↑
Device-nGRE (允许 Reordering)
↑
Device-GRE (最宽松:允许 Gathering)
保守原则在此的具体表现 :两级页表中只要有一级标记为 Device 子类型,结果就是对应的 Device 子类型。例如 Stage 1 标记为 Device-GRE,Stage 2 标记为 Normal Write-Back,最终结果就是 Device-GRE(因为 Device 优先级高于 Normal)。
3. 缓存属性(Cacheability)合并
对于 Normal 类型内存,两级页表的缓存策略也需要合并。规则同样遵循保守策略------以更不缓存的级别为准。
3.1 合并规则表
| Stage 1 | Stage 2 | 最终缓存属性 |
|---|---|---|
| Non-cacheable | 任意 | Non-cacheable |
| 任意 | Non-cacheable | Non-cacheable |
| Write-Through | Write-Through | Write-Through |
| Write-Through | Write-Back | Write-Through |
| Write-Back | Write-Through | Write-Through |
| Write-Back | Write-Back | Write-Back |
总结:
- 任意一级为
Non-cacheable,结果就是Non-cacheable。 - 两级都是
Write-Through或都是Write-Back,则保持不变。 - 两级不一致时,取更保守 的
Write-Through(因为 Write-Through 写的时候会同步到主存,安全性更高)。
3.2 FWB 特殊规则
当 HCR_EL2.FWB == 0 且 Stage 2 的 MemAttr[3:0] == 0b1111 时,合并后的内存类型和缓存属性直接采用 Stage 1 的输出,不再做额外合并。这相当于给 Guest OS 提供了一种"绕过" Stage 2 缓存限制的能力。
4. MTE 权限属性合并(FEAT_MTE_PERM)
当系统实现了 FEAT_MTE_PERM(Memory Tagging Extension 权限扩展)时,Tagged 属性的合并规则如下:
| Stage 1 | Stage 2 | 最终结果 |
|---|---|---|
| Normal Write-Back | 任意 | Normal Write-Back |
| Normal Write-Back, Tagged | Normal Write-Back | Normal Write-Back, Tagged |
| Normal Write-Back, Tagged | Normal Write-Back, NoTagAccess | Normal Write-Back, Tagged, NoTagAccess |
注意:如果任一级是 Device / Non-cacheable / Write-Through 类型,则 Tagged 属性被视为不存在。
5. 可共享性(Shareability)属性合并
Shareability 属性的合并规则不受 HCR_EL2.FWB 影响,独立生效。
5.1 特殊内存类型
以下内存类型强制为 Outer Shareable,无需查表:
- 所有 Device 类型
- Normal Inner Non-cacheable, Outer Non-cacheable
5.2 Normal 类型合并规则
| Stage 1 | Stage 2 | 最终 Shareability |
|---|---|---|
| Outer Shareable | 任意 | Outer Shareable |
| Inner Shareable | Outer Shareable | Outer Shareable |
| Inner Shareable | Inner Shareable | Inner Shareable |
| Inner Shareable | Non-shareable | Inner Shareable |
| Non-shareable | Outer Shareable | Outer Shareable |
| Non-shareable | Inner Shareable | Inner Shareable |
| Non-shareable | Non-shareable | Non-shareable |
理解:
Outer Shareable具有最强的传播范围,两级中有一级为 Outer Shareable 就取 Outer Shareable。Non-shareable的传播范围最小,不会升级到 Inner Shareable,但会被 Outer Shareable 升级。- 两级都是 Non-shareable 时,保持 Non-shareable。
6. 实用建议
6.1 虚拟化驱动开发
在编写运行在 Hypervisor 上的设备驱动时,以下几点需要注意:
-
Device 内存优先:如果设备寄存器被映射为 Device 类型,即使 Guest OS 的页表标记为 Normal,Hypervisor 的 Stage 2 页表也能将其纠正为 Device,从而避免不必要的缓存。
-
缓存策略一致:尽量让 Stage 1 和 Stage 2 的缓存策略保持一致,以避免不必要的降级(Write-Back 降为 Write-Through 会显著影响 DMA 性能)。
-
共享内存:用于多核间通信或与 Hypervisor 共享的内存,应确保两级 Shareability 属性都为 Inner Shareable,以获得最佳性能。
6.2 调试技巧
当发现内存访问行为异常(如写入未同步、缓存一致性问题)时,可以从以下角度排查:
- 通过
perf或 ARM PMU 观察缓存命中率变化。 - 使用 ARM 的
ATS1E1R/ATS1E2R指令查询当前地址翻译结果中的内存属性。 - 检查
HCR_EL2.FWB的设置,理解是否存在 FWB 强制覆盖的行为。
7. 总结
ARMv8 两级页表的属性合并核心思想是保守优先:
Device > Normal
Non-cacheable > Write-Through > Write-Back
Outer Shareable > Inner Shareable > Non-shareable