RISCV的smstateen-ssstateen扩展
RISC-V 的 Smstateen / Ssstateen 扩展是为了解决安全性和资源隔离性问题而设计的,尤其是针对在多个上下文(如用户线程、多个虚拟机)之间 潜在的隐蔽信道(covert channel) 风险。
🌐 背景:隐蔽信道与上下文切换问题
当 RISC-V 扩展引入新的硬件状态(如新的 CSR 寄存器)时,如果操作系统或 hypervisor 不了解这些状态的存在,就不会在上下文切换时保存和恢复它们。
这会导致:
- 一个线程或虚拟机修改某些寄存器;
- 另一个线程/虚拟机读取到这个未清除的状态;
- 从而形成 隐蔽信道,泄露信息。
例子:
- AIA 扩展增加了多个 supervisor 级 CSR,如
siselect
,sireg
,stopi
等; - 如果 hypervisor 不支持 AIA,就不会保存这些 CSR;
- 多个 guest OS 就能通过它们通信,违背隔离性原则。
✅ 已有的解决方法(部分)
对于 F(浮点) 和 V(向量) 扩展,RISC-V 定义了:
FS
字段(用于浮点扩展);VS
字段(用于向量扩展);
这些字段位于sstatus
CSR 中,可以禁止访问对应寄存器,防止未管理状态的使用。
❌ 问题:FS/VS 方案的不足
- 不能为所有扩展都分配 XS 字段;
sstatus
位数有限(尤其在 RV32 上),不能无限添加新字段;- 所以需要一个专门的新机制来管理“状态访问许可”。
✅ Smstateen / Ssstateen 扩展简介
目标:
提供一种统一方式:
- 控制低特权级对某些扩展状态的访问;
- 防止未管理状态造成信息泄露。
🧱 CSR 结构一览
🧭 Machine Level(M-mode)
mstateen0
–mstateen3
(RV64 为 64-bit,共 256 bits)- RV32 补充:
mstateen0h
–mstateen3h
🧭 Supervisor Level(S-mode)
sstateen0
–sstateen3
(32-bit,共 128 bits)- 没有高位 CSR,约定上层 32 位始终为 0
🧭 Hypervisor Level(VS-mode 控制)
hstateen0
–hstateen3
(64-bit)- RV32 补充:
hstateen0h
–hstateen3h
🔒 每个 stateen bit 的含义
- 每个 bit 控制一个扩展状态的访问权限;
- 设为 0 时,低特权级访问相关状态(寄存器、CSR)会:
- 抛出
illegal instruction
; - 或在 VS/VU 模式下抛出
virtual instruction exception
;
- 抛出
- 若扩展未实现,或 bit 尚未定义,则该位是只读 0(read-only zero);
🔄 继承与关系(mstateen/hstateen/sstateen)
- 所有状态权限控制从 M-mode 向下传播:
mstateenX[bit]
为 0 → 对应hstateenX[bit]
和sstateenX[bit]
为只读 0;hstateenX[bit]
为 0 →sstateenX[bit]
为只读 0;sstateenX[bit]
不能是只读 1,除非对应上层是只读 1;
- Bit 63:
- 控制是否允许访问对应编号的
sstateenX
或hstateenX
; - 举例:
mstateen0[63]
控制是否允许访问sstateen0
和hstateen0
;
- 控制是否允许访问对应编号的
📘 具体字段解释(以 mstateen0
为例)
Bit | 名称 | 控制内容 |
---|---|---|
63 | SE0 | 控制访问 sstateen0 , hstateen0 |
62 | ENVCFG | 控制访问 senvcfg , henvcfg |
60 | CSRIND | 控制 siselect , sireg* , vsireg* |
59 | AIA | 控制 AIA 除 CSRIND/IMSIC 外状态 |
58 | IMSIC | 控制 stopei , vstopei 等中断控制 CSR |
57 | CONTEXT | 控制 scontext , hcontext |
56 | PIP13 | 控制 hedeleg (1.13 扩展) |
55 | SRMCFG | 控制 srmcfg (Ssqosid 扩展) |
54 | CTR | 性能计数器相关状态访问 |
7 | JVT | 控制 jvt (Zcmt 扩展) |
6 | FCSR | 控制 fcsr (在 misa.F = 0 时有效) |
🧩 使用规范(Usage)
启动时:
- 所有
mstateen*
位默认初始化为 0(不能访问); - 若 M-mode 允许访问某状态 → 显式设置对应 bit;
- 设置后,还必须:
- 将
hstateen*
和sstateen*
对应位初始化为 0; - 因为它们的初始内容由上级决定;
- 将
S-mode OS 启动时:
- 初始化
sstateen*
全为 0; - 按需启用对应 bit,前提是该 OS 会管理该状态(例如在上下文切换中保存/恢复);
Hypervisor 模式下:
- 需要保存/恢复
sstateen*
,因为它是 Guest OS 的状态; - 如果要禁止访问某个
sstateen*
,设置对应hstateen*
的 bit 为 0 即可;
🧩 mstateen.X[63]=1
且 hstateen.X[63]=1
,sstateen.X[63]
的 bit 63 才能为 1
即 hstateen 为 1,VS mode 的 OS 可以访问 sstateen,此时配置 VU 模式下 用户空间的寄存器组(浮点寄存器组、计数器寄存器组等)的访问权限。
✅ 这是为了逐级控制,防止越权访问
mstateenX[63]
控制是否允许访问hstateenX
和sstateenX
,控制 S/VU/VS;hstateenX[63]
控制是否允许访问sstateenX
,控制 VS/VU;sstateenX[63]
控制是否允许 U-mode / VU-mode 访问某个状态,控制 U/VU。
🚫 若上层 bit 为 0,则下层 无权设置为 1
因此,如果:
mstateenX[63] == 0
:machine 模式根本不允许访问sstateenX
→sstateenX[63]
被强制为只读 0;hstateenX[63] == 0
:hypervisor 模式不允许访问sstateenX
→sstateenX[63]
同样为只读 0;- 只有当这两个都为 1,
sstateenX[63]
才能为可写 1。
⚠️ 作用:
确保低权限级别不能启用状态访问,除非所有更高层都授权了该访问权限。这相当于一个层级访问控制链,任何一层禁用,即全链条断开。
🧩 hstateen 的角色
hstateenX
是在 VS/VU 模式下,控制虚拟机对状态访问的权限。它位于 hypervisor 级别(H-mode),作用是:
🎯 控制哪些扩展状态可供 guest OS 使用:
- 当虚拟机运行于 VS-mode / VU-mode 时,访问某扩展状态前:
- 需要
hstateenX[bit] = 1
; - 也需要
mstateenX[bit] = 1
; - 否则触发虚拟异常或非法指令异常。
- 需要
🛡️ 控制 sstateenX
的可访问性:
hstateenX[63]
控制是否允许 guest OS 访问sstateenX
;- 这是为了确保 hypervisor 能决定 guest OS 是否能配置用户态访问某些扩展状态。
🔁 总结依赖关系图(权限链):
M-mode│┌───────▼────────┐│ mstateenX[bit] │ ← 顶层授权:控制所有下层访问└───────┬────────┘│+------+------+| |hstateenX[bit] (if H ext.)│ |▼ ▼VS-mode sstateenX[bit]│▼U-mode/VU-mode
- 若任何一级为 0,下层该 bit 就强制为只读 0。
mstateenX[63]
→ 允许访问hstateenX
和sstateenX
;hstateenX[63]
→ 允许访问sstateenX
;sstateenX[bit]
→ 允许 U/VU 模式使用扩展状态。
总结
完结撒花!