⬢ DragonFlyBSD Kernel Audit
DF-5586 / fix.diff
← back to finding ↓ download raw
--- a/sys/platform/vkernel64/x86_64/exception.c
+++ b/sys/platform/vkernel64/x86_64/exception.c
@@ -267,7 +267,20 @@
 
 	save = errno;
 	kern_trap((struct trapframe *)&ctx->uc_mcontext.mc_rdi);
-	splz();
+	/*
+	 * Dispatch deferred interrupts only when returning to a base-level
+	 * context.  pc64 doreti refuses to unpend interrupts while the
+	 * interrupted thread holds a critical section (ipl.s: "If we are
+	 * in a critical section we cannot run any pending ints"), and
+	 * lwkt_maybe_splz() additionally requires nesting==0 and
+	 * td_nest_count < 2.  The fault may have interrupted a critical
+	 * section or another interrupt's signal handler.
+	 */
+	if (curthread->td_critcount == 0 &&
+	    mycpu->gd_intr_nesting_level == 0 &&
+	    curthread->td_nest_count < 2) {
+		splz();
+	}
 	errno = save;
 }