首页/指令库/SSPOPCHK
SSPOPCHK

RISC-V SSPOPCHK 指令详解

指令手册SYSTEM (MOP.R.28)

xSSE=1 时,SSPOPCHK 从 ssp 读取影子返回地址并与 x1/x5 比较。

指令语法

sspopchk rs1

RV32/RV64 Zicfiss(依赖 Zicsr、Zimop、Zaamo);sspopchk rs1,rs1 仅 x1/x5。

32 位 SYSTEM:bits31:20=110011011100、funct3=100、opcode=1110011;rs1 是比较源,rd=00000。

xSSE=1 时读取 mem[ssp] 并与源逐位比较;匹配且读取成功才令 ssp+=XLEN/8。不匹配为 software-check(cause=18、xtval=3),不写源寄存器。

S-mode 已实现时,M 的 xSSE=0,S/HS 取 menvcfg.SSE、VS 取 henvcfg.SSE、U/VU 取 senvcfg.SSE;无 S-mode 时 M/U 均为 0。兼容行为要求支持 Zimop。xSSE=0 时不访问影子栈且不更新 ssp;活动时未按 XLEN 对齐产生 store/AMO access-fault。

Zicfiss安全机制

指令行为说明

xSSE=1 时,SSPOPCHK 从 ssp 指向的影子栈读取返回地址,与 x1 或 x5 中的链接寄存器值逐位比较;不匹配时触发 software-check 异常,匹配且读取成功后 ssp 增加 XLEN/8。

SSPOPCHK 指令解析与执行动画

只显示规范定义的编码、条件和架构可见状态。

sspopchk x1
sspopchk
执行环境

假定 Zicfiss 与 Zimop 已实现;xSSE 是当前模式按规范确定的启用状态。ssp 的低两位必须为零;RV64 允许 bit2=1 的输入假定实现也支持 32 位模式。complete 表示影子栈访问保护通过。步骤不代表处理器周期。

指令编码
31..20
MOP.R.28
110011011100
19..15
rs1
00001
14..12
funct3
100
11..7
rd
00000
6..0
opcode
1110011 SYSTEM
解码固定字段
ssp=0x0000000000002000, x[x1]=0x0000000012345678, mem[ssp]=0x0000000012345678
ssp <- 0x0000000000002008
尚未提交架构状态。

快速理解与检索要点

SSPOPCHK 是 Zicfiss 影子栈检查指令;xSSE 和访问结果决定是否比较和更新 ssp。

隐式使用 ssp,访问宽度为 XLEN;xSSE=0 时不访问影子栈且不更新 ssp。
需要 Zimop 支持才能在 Zicfiss 未实现或未激活时提供 MOP 兼容行为;没有 Zimop 的处理器可能触发非法指令异常。

常见使用场景

函数调用与返回

假定 RV64 Zicfiss、S-mode、menvcfg.SSE=1(xSSE=1)、ssp=0x2000。x1 与 mem[0x2000] 均为 0x12345678,合法加载成功且比较匹配后 ssp=0x2008;x1 不变。

影子栈检查与展开

假定 RV64 Zicfiss、S-mode、menvcfg.SSE=1(xSSE=1)、ssp=0x2000。x1 与 mem[0x2000] 均为 0x12345678,合法加载成功且比较匹配后 ssp=0x2008;x1 不变。

使用前检查清单

语法检查
  • RV32/RV64 Zicfiss(依赖 Zicsr、Zimop、Zaamo);sspopchk rs1,rs1 仅 x1/x5。
  • 32 位 SYSTEM:bits31:20=110011011100、funct3=100、opcode=1110011;rs1 是比较源,rd=00000。
语义检查
  • xSSE=1 时读取 mem[ssp] 并与源逐位比较;匹配且读取成功才令 ssp+=XLEN/8。不匹配为 software-check(cause=18、xtval=3),不写源寄存器。
  • S-mode 已实现时,M 的 xSSE=0,S/HS 取 menvcfg.SSE、VS 取 henvcfg.SSE、U/VU 取 senvcfg.SSE;无 S-mode 时 M/U 均为 0。兼容行为要求支持 Zimop。xSSE=0 时不访问影子栈且不更新 ssp;活动时未按 XLEN 对齐产生 store/AMO access-fault。

容易混淆 / 常见误区

该指令只支持 x1 或 x5 作为被比较的链接寄存器。
Zicfiss 依赖 Zicsr、Zimop 和 Zaamo 扩展。
影子栈值不匹配会触发 software-check 异常。
store/AMO access-fault 的优先级高于 software-check;若隐式 ssp 加载产生 store/AMO page-fault 或 guest-page-fault,则不比较且 ssp 不更新。
若 ssp 未按 XLEN 对齐,SSPOPCHK 会产生 store/AMO access-fault。
访问内存必须是幂等的,并且 PMP 必须允许读写;否则会产生 store/AMO access-fault。
异常行为取决于当前特权级、环境配置 CSR 和页表/内存属性。
只有加载成功且比较通过后,ssp 才增加 XLEN/8。

常见问题

SSPOPCHK 未启用相关 CFI 时会怎样?

xSSE=0 时,SSPOPCHK 不访问影子栈且不更新 ssp。未实现 Zicfiss 但支持 Zimop 时也按 MOP 行为执行;没有 Zimop 支持则可能触发非法指令异常。

SSPOPCHK 的官方来源是什么?

The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture 的 Control-flow Integrity 章节定义此指令;Volume II: Privileged Architecture 定义启用状态与影子栈内存保护。