diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c --- a/sys/riscv/riscv/trap.c +++ b/sys/riscv/riscv/trap.c @@ -227,11 +227,6 @@ pcb = td->td_pcb; stval = frame->tf_stval; - if (td->td_critnest != 0 || td->td_intr_nesting_level != 0 || - WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL, - "Kernel page fault") != 0) - goto fatal; - if (usermode) { if (!VIRT_IS_VALID(stval)) { call_trapsignal(td, SIGSEGV, SEGV_MAPERR, (void *)stval, @@ -244,7 +239,8 @@ * Enable interrupts for the duration of the page fault. For * user faults this was done already in do_trap_user(). */ - intr_enable(); + if ((frame->tf_sstatus & SSTATUS_SIE) != 0) + intr_enable(); if (stval >= VM_MIN_KERNEL_ADDRESS) { map = kernel_map; @@ -283,6 +279,11 @@ } } + if (td->td_critnest != 0 || td->td_intr_nesting_level != 0 || + WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL, + "Kernel page fault") != 0) + goto fatal; + done: if (usermode) userret(td, frame);