Skip to content

Commit

Permalink
riscv_syscall.S: Fix a massive bug in syscall dispatch logic
Browse files Browse the repository at this point in the history
There is an enormous error in the system call dispatch logic; if a task
is inside a critical section (local interrupts disabled) there is a chance
that during a context switch when the task resumes, local interrupts are
erroneously ENABLED. This obviously leads to unexpected crashes and such.

This happens when the CPU status has Previous Interrupt Enable (PIE) set
to 1, even though Interrupt Enable (IE) is set to 0.

When the system call returns via ERET, the CPU sets PIE->IE and if PIE=1
interrupts get enabled.

This is fixed easily by explicitly CLEARING PIE from the register save
area, if IE=0 when the system call was started.
  • Loading branch information
pussuw committed Nov 12, 2024
1 parent 3873bcc commit ef34d05
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion arch/risc-v/src/common/supervisor/riscv_syscall.S
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,13 @@ sys_call6:
and s0, s0, s1
li s1, STATUS_PIE /* set PIE */
or s0, s0, s1
j 2f

1:
1:
li s1, ~STATUS_PIE /* else: clear PIE */
and s0, s0, s1

2:
/* Set previous privilege, we are in privileged mode now */

li s1, STATUS_PPP /* set previous privilege */
Expand Down

0 comments on commit ef34d05

Please sign in to comment.