更多精彩,请点击上方
蓝字关注我
前言:
RISC-V(发音为“risk-five”)是一种新的指令集架构(ISA),最初的设计目的是支持计算机架构的研究和教育,但随着近些年的发展,它已经成为工业实现中的一个标准化、免费且开放的架构。
RISC-V 指令集的一大优势是其可扩展性,本文介绍Zicfilp扩展。(所有spec下载:我整理了RISC-V所有spec(附下载链接))
着陆垫机制(Zicfilp扩展)通过限制间接跳转和调用指令的目标地址必须是指令序列中特定点(即着陆垫)来工作。这可以防止攻击者将控制流重定向到任意地址。属于RISC-V CFI扩展的一部分,其相关介绍可参考RISCV控制流完整性扩展-CFI
本文为Zicfilp扩展在特权指令集(卷二)中的个人总结。
一、着陆垫启用(LPE)状态
新增加xLPE bit,用于判定在某一特权模式下,使用Zicfilp扩展提供的着陆垫时,前向边控制流完整性是否启用。其判定逻辑根据S模式是否实现分为两种场景:
S模式已实现时:xLPE的启用状态由M模式与S模式的相关控制逻辑共同决定
S模式未实现时:xLPE的启用状态仅由M模式的控制逻辑决定
二、陷阱发生时预期着陆垫状态(ELP)的处理
2.1 陷阱触发的时机与异常优先级
2.1.1 陷阱触发时机
在执行JALR/C.JALR/C.JR指令完成后、间接调用/跳转的目标指令解码前,若出现以下两类优先级高于“着陆垫故障(code=2)”软件检查异常的情况,陷阱需递交至相同或更高特权模式:
异步中断
同步异常
2.1.2 异常优先级规则
Zicfilp扩展引入的软件检查异常优先级遵循以下排序:指令访问故障 > Zicfilp软件检查异常 > 非法指令异常。(大体位于下图红框的位置)
2.2 陷阱触发的核心场景
当预期着陆垫状态(ELP)为LP_EXPECTED时,满足以下任一条件将触发陷阱并递交至相同或更高特权模式:
执行非LPAD指令导致的软件检查异常;
执行LPAD指令本身导致的软件检查异常。
2.3 ELP的保存机制
为确保陷阱返回时能恢复触发前的ELP状态,陷阱递交过程需通过新增控制状态寄存器(CSR)位存储前序ELP值,不同特权模式对应的存储位定义如下表:
目标特权模式 |
存储前序ELP的CSR及对应位 |
补充说明 |
|---|---|---|
M模式 |
mstatus 寄存器 - MPELP位 |
陷阱递交至M模式时存储 |
S模式 / HS模式 |
mstatus 寄存器 - SPELP位 |
可通过sstatus寄存器访问 |
VS模式 |
vsstatus 寄存器 - SPELP位 |
vsstatus为S模式sstatus的VS模式版本 |
调试模式 |
dcsr 寄存器 - pelp位 |
切换至调试模式时存储 |
RNMI(不可屏蔽中断) |
mnstatus 寄存器 - 新增对应位 |
需配合Smrnmi扩展实现 |
2.4 ELP的保存与恢复流程
2.4.1 陷阱进入时的ELP保存
当陷阱触发并进入特权模式x时,执行以下操作:
将当前ELP值写入x模式对应的存储位(xPELP/pelp);
将ELP状态置为NO_LP_EXPECTED(无预期着陆垫状态)。
2.4.2 特权模式陷阱返回时的ELP恢复
M模式通过MRET指令、S模式通过SRET指令完成陷阱返回,通用恢复逻辑如下:
执行xRET指令时,若目标特权模式为y:
若y模式的着陆垫启用位(yLPE,见1. 着陆垫启用状态)为1,则将ELP设为xPELP的值;
若yLPE为0,则将ELP置为NO_LP_EXPECTED,并将xPELP重置为NO_LP_EXPECTED。
2.4.3 调试模式的ELP保存与恢复
进入调试模式:dcsr寄存器的pelp位更新为硬件线程(hart)触发调试前所在特权级的ELP值,同时ELP置为NO_LP_EXPECTED;
从调试模式恢复:若目标特权模式为y且yLPE为1,则ELP设为pelp位的值;否则ELP置为NO_LP_EXPECTED。
2.4.4 RNMI陷阱的ELP处理(需Smrnmi扩展)
不可屏蔽中断陷阱(RNMI trap)的进入与MNRET指令的恢复过程,遵循与上述一致的ELP保存-恢复逻辑,对应的mnstatus寄存器中新增了存储前序ELP的专用位。
相关阅读:

