SEV-SNP隔离原理:NPT、RMP与硬件强制

hypervisor 负责翻译地址,可它自己又不可信——SEV-SNP 是怎么让”不可信的管家”干活、又防住它偷东西的?

📚 基本概念速读

名称 定义 省流
hypervisor 虚拟机监控器(VMM) 云上管虚拟机的软件层
嵌套分页 Nested Paging,两层地址翻译 虚拟机地址翻译机制
NPT Nested Page Table,嵌套页表 hypervisor 建的翻译规则
RMP Reverse Map Table,反向映射表 硬件记录的”物理页归谁”事实
RMPE RMP Entry,RMP 条目 每 4KB 物理页一条记录
ASID Address Space Identifier,地址空间标识符 每个 CVM 的唯一身份编号
VMCB Virtual Machine Control Block,虚拟机控制块 存 VM 状态和 ASID 的控制块
VMRUN/VMEXIT 进出虚拟机的特权指令 硬件切换”当前身份”的开关
VMPL Virtual Machine Privilege Level,虚拟机特权级 VM 内部的 4 级权限
PSP Platform Security Processor,平台安全处理器 AMD CPU 里的独立安全小电脑
#PF Page Fault,缺页异常 硬件拒绝访问时的信号

🧩 为什么需要 SNP:第一代 SEV 的漏洞

先看虚拟机地址翻译。虚拟机里的地址要翻译两次才能到真实物理地址:

1
2
3
4
Guest 认为的地址(GVA) → Guest 页表 → Guest 物理地址(GPA)


hypervisor 的嵌套页表(NPT) → 真实物理地址(SPA)

这里的 NPT 由 hypervisor 管理。问题来了:hypervisor 不可信,它可以:

攻击 做法 后果
偷换内容 把 VM 的某个 GPA 悄悄重映射到别的物理页 VM 读到被替换的假数据
数据串扰 把 VM 的页映射给另一个 VM 两个租户数据互相泄露
直接偷读 把自己映射到 VM 的页 读取 VM 内存

第一代 SEV 只做内存加密,防不了这种重映射/篡改。加密只保证”别人读不懂”,但 hypervisor 可以”把读的对象换掉”。这就是 SNP 要补的洞。

🔍 RMP:反向映射表,硬件管的”所有权事实”

SNP(Secure Nested Paging,安全嵌套分页) 的核心是引入 RMP(Reverse Map Table,反向映射表)

1
2
3
4
5
RMP:每 4KB 物理页一行,硬件强制记录:
┌──────────┬───────────┬──────────┐
│ 物理页地址 │ 属于哪个VM │ 权限/状态 │
│ (SPA) │ (ASID) │ │
└──────────┴───────────┴──────────┘

“反向”的含义:NPT 是 hypervisor 往前翻译”地址去哪”,RMP 是硬件反过来锁”这页是谁的、谁才能动”。

一句话对比:

谁维护 管什么 本质
NPT hypervisor(软件) 地址往哪翻 路由规则
RMP CPU 硬件 翻过去之后你有没有资格碰 所有权事实

hypervisor 能改路由规则,但改不了所有权事实——事实由 PSP 固件锁定。所以 hypervisor 怎么折腾 NPT 都是白费力气,最终判定权在硬件手里。

🔒 硬件强制执行是怎么实现的

“硬件强制执行,谁也绕不过”靠两把锁

锁 1:RMP 表的内容,软件改不了

1
2
3
4
5
RMP 表本身也是内存里的一个区域,但是:
· 表的物理位置由 CPU 内部寄存器(MSR)记录,且该区域对软件是"保留区"
—— hypervisor 想读写这块内存,直接被拒
· 修改 RMP 表的唯一入口是 RMPUPDATE 指令,而该指令由 CPU 固件(PSP)把关
—— 页一旦分配并激活给某个 CVM,PSP 就拒绝再改它的归属

锁 2:检查逻辑固化在硬件翻译路径里,软件绕不过

1
2
3
4
5
6
7
RMP 检查不是"一段软件代码",而是 CPU 微码/硬件逻辑的一部分,
它嵌在每次地址翻译的必经之路上:

访存请求 → MMU 做 NPT 翻译 → 【微码强制执行 RMP 检查】 → 通过才放行

└─ 这段逻辑没有"跳过开关",任何软件
都插不进手

类比:高速公路入口的自动测速摄像头——你(hypervisor)只能决定”开多快”(建 NPT 规则),但摄像头拍不拍、罚不罚,是硬件自动执行的,你没有权限关掉它。

🪪 访问者身份怎么判定:ASID

ASID(Address Space Identifier,地址空间标识符)——每个 CVM 一个唯一编号。身份从哪来?怎么保证伪造不了?

1
2
3
4
① 每个 CVM 启动时分配一个 ASID(如 VM-A=16, VM-B=17)
② ASID 记录在 VMCB(虚拟机控制块)里
③ CPU 执行 VMRUN 进入该 VM 时,硬件把 ASID 装载为"当前身份"
④ 之后该 VM 的所有内存访问,都自动携带这个身份

判定流程(硬件完成,一次访存)

1
2
3
4
5
6
7
8
9
10
11
12
13
访存到达物理页 SPA


读 RMPE:这页 assigned 给 ASID=16


比较"当前访问者身份" vs "页归属 ASID"

├── 当前身份 == 16(就是 VM-A)→ ✅ 通过(再查 VMPL 权限)

├── 当前身份是 hypervisor(host 域)→ ❌ 拒绝 #PF

└── 当前身份 == 17(VM-B)→ ❌ 拒绝 #PF

为什么软件伪造不了身份?

1
2
3
4
5
· "当前 ASID"是 CPU 内部状态,由 VMRUN / VMEXIT 这两个特权指令
自动切换,guest 软件碰不到这个状态
· VM 想伪装成 hypervisor?它连 VMRUN/VMEXIT 都执行不了(特权指令)
· hypervisor 想把 ASID 改成别人的?ASID 记录在 RMPE 里,
分配由 CPU 固件(PSP)完成,分配后 hypervisor 改不了

类比:VMRUN 就是”刷门禁卡进房间”,CPU 是门禁系统本身。门禁系统自己知道”现在里面是谁”——它不需要房间里的人来汇报身份,因为它就是放你进去的那个系统。

🧩 关键澄清:hypervisor 只是”提供规则”,不是”执行翻译”

这是最容易混的点。页表是谁建的 ≠ 翻译是谁执行的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
你以为的访存路径:
guest 应用 → 翻译 → hypervisor 跑过来翻译 GPA→SPA → hypervisor 去访问

└─ 这样确实"访问者全是 hypervisor"

实际上的访存路径:
guest 应用执行一条访存指令


CPU 硬件(MMU)自动完成两次翻译 ← 翻译是 CPU 电路做的,不经过 hypervisor 的代码
GVA→GPA(用 guest OS 建的页表)
GPA→SPA(用 hypervisor 建的 NPT 表)


CPU 硬件查 RMP


通过→访存 / 拒绝→#PF

关键事实:GPA→SPA 的翻译虽然规则表(NPT)是 hypervisor 写的,但翻译这个动作是 CPU 硬件执行的,hypervisor 的代码根本没机会跑在访存路径上。NPT 是 hypervisor 画的”地图”,但走路的是 CPU。

最后一块拼图:hypervisor 造假 NPT 也没用

1
2
3
4
5
6
7
8
9
10
hypervisor 写 NPT:VM-A 的 GPA X → 物理页 P(其实是 VM-B 的页)


VM-A 访存 X → CPU 翻译到物理页 P → 查 RMP


RMP 说:页 P 归属 ASID=17(VM-B),你当前身份 ASID=16


❌ 硬件拒绝(#PF)

📋 典型场景对照

访问者身份(当前 ASID) 目标页归属(RMPE.ASID) 判定
VM-A (16) 16(自己) ✅ 允许
VM-A (16) 17(VM-B 的页) ❌ 拒绝
hypervisor 16(CVM 的页) ❌ 拒绝
hypervisor 未分配页 ✅ 允许(host 自己的内存)

补充两个细节:

  • VMPL(Virtual Machine Privilege Level):SEV-SNP 还给每个 VM 内部划分 4 个特权级(VMPL0~3),RMPE 里分别记录各级的读/写/执行权限。ASID 管”是不是这家的”,VMPL 管”这家里面谁有权碰”。
  • 设备 DMA 同样受限:设备要通过 IOMMU(AMD-Vi)访问内存,IOMMU 域也关联 ASID,hypervisor 不能直接把设备 DMA 指向 CVM 的私有页。

⚠️ 常见误区

误区 正解
hypervisor 查 RMP 查 RMP 的是 CPU 硬件,不是 hypervisor——它是裁判,不能当运动员
hypervisor 执行地址翻译 翻译由 CPU 的 MMU 硬件执行,hypervisor 只提供 NPT 规则表
hypervisor 改 NPT 就能访问 CVM 内存 NPT 是路由规则,RMP 是所有权事实,路由改了也过不了所有权检查
内存加密就够防篡改 加密只防”读不懂”,SNP/RMP 才是防”偷换、重映射”的关键
ASID 是软件声明的身份 ASID 是硬件通过 VMRUN/VMEXIT 自动维护的内部状态,软件伪造不了
RMP 表软件可以随便改 RMP 区域对软件保留,唯一入口 RMPUPDATE 由 PSP 固件把关

✅ 总结

SEV-SNP 用 RMP 把”物理页归谁”这个事实从软件手里夺走,交给硬件记录并强制执行;翻译和判定都由 CPU 硬件执行,hypervisor 只提供页表规则;“当前访问者”是硬件通过 VMRUN/VMEXIT 自动维护的 ASID 状态,谁都无法伪造——NPT 管”地址往哪翻”,RMP 管”翻过去之后你有没有资格碰”。

下一站:TPM——用户能直接摸到的白盒信任根。

Happy Hacking! 🎉