Hi Zong,
On Thu, Jun 19, 2025 at 7:16 PM Zong Li zong.li@sifive.com wrote:
On Mon, Jun 16, 2025 at 3:31 PM Zong Li zong.li@sifive.com wrote:
On Thu, Jun 5, 2025 at 1:17 AM Deepak Gupta debug@rivosinc.com wrote:
zicfiss / zicfilp introduces a new exception to priv isa `software check exception` with cause code = 18. This patch implements software check exception.
.....
When a user mode CFI violation occurs, the ELP state should be 1, and the system traps into supervisor mode. During this trap, sstatus.SPELP is set to 1, and the ELP state is reset to 0. If we don’t clear sstatus.SPELP, the ELP state will become 1 again after executing the sret instruction. As a result, the system might trigger another forward CFI violation upon executing the next instruction in the user program, unless it happens to be a lpad instruction.
The previous patch was tested on QEMU, but QEMU does not set the sstatus.SPELP bit to 1 when a forward CFI violation occurs. Therefore, I suspect that QEMU might also require some fixes.
Hi Deepak, The issue with QEMU was that the sw-check exception bit in medeleg couldn't be set. This has been fixed in the latest QEMU mainline. I have re-tested the latest QEMU version, and it works.
What was this issue, can you point me to the patch in mainline?
Thanks
if (is_fcfi || is_bcfi) {
do_trap_error(regs, SIGSEGV, SEGV_CPERR, regs->epc,
"Oops - control flow violation");
return true;
}
return false;
+}
+/*
- software check exception is defined with risc-v cfi spec. Software check
- exception is raised when:-
- a) An indirect branch doesn't land on 4 byte aligned PC or `lpad`
- instruction or `label` value programmed in `lpad` instr doesn't
- match with value setup in `x7`. reported code in `xtval` is 2.
- b) `sspopchk` instruction finds a mismatch between top of shadow stack (ssp)
- and x1/x5. reported code in `xtval` is 3.
- */
+asmlinkage __visible __trap_section void do_trap_software_check(struct pt_regs *regs) +{
if (user_mode(regs)) {
irqentry_enter_from_user_mode(regs);
/* not a cfi violation, then merge into flow of unknown trap handler */
if (!handle_user_cfi_violation(regs))
do_trap_unknown(regs);
irqentry_exit_to_user_mode(regs);
} else {
/* sw check exception coming from kernel is a bug in kernel */
die(regs, "Kernel BUG");
}
+}
#ifdef CONFIG_MMU asmlinkage __visible noinstr void do_page_fault(struct pt_regs *regs) {
-- 2.43.0