mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 04:13:11 +00:00
Kernel/riscv64: Increment sepc before re-enabling interrupts
This otherwise caused a race condition between the signal dispatcher (which sets sepc to the signal trampoline) and sepc being updated in the trap handler. We obviously have to keep the sepc set by the signal dispatcher and not increment it afterwards.
This commit is contained in:
parent
c87e32154a
commit
6cd130ec8e
|
@ -42,6 +42,11 @@ extern "C" void trap_handler(TrapFrame& trap_frame)
|
|||
{
|
||||
auto scause = trap_frame.regs->scause;
|
||||
|
||||
// sepc has to point to the instruction following the ecall when returning from a syscall, unless it is changed by the syscall handler.
|
||||
// We have to increment sepc before interrupts are re-enabled, as code triggered by interrupts also can cause sepc to be updated.
|
||||
if (scause == RISCV64::CSR::SCAUSE::EnvironmentCallFromUMode)
|
||||
trap_frame.regs->sepc += 4;
|
||||
|
||||
if ((to_underlying(scause) & RISCV64::CSR::SCAUSE_INTERRUPT_MASK) != 0) {
|
||||
// Interrupt
|
||||
|
||||
|
@ -105,7 +110,6 @@ extern "C" void trap_handler(TrapFrame& trap_frame)
|
|||
}
|
||||
|
||||
case EnvironmentCallFromUMode:
|
||||
trap_frame.regs->sepc += 4;
|
||||
syscall_handler(&trap_frame);
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in a new issue