aboutsummaryrefslogtreecommitdiff
path: root/sys/pc98
diff options
context:
space:
mode:
authorKATO Takenori <kato@FreeBSD.org>2001-05-02 13:56:50 +0000
committerKATO Takenori <kato@FreeBSD.org>2001-05-02 13:56:50 +0000
commit92c90d5cd1fe228519ca1181e22538b60d189717 (patch)
tree1582253d3a904b4479848592590a7da6b12e13e7 /sys/pc98
parent3520a2a0e2a00bdefc719bd27b04796cacd4c4da (diff)
Notes
Diffstat (limited to 'sys/pc98')
-rw-r--r--sys/pc98/pc98/npx.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/sys/pc98/pc98/npx.c b/sys/pc98/pc98/npx.c
index 30b671162191..25e8dc812397 100644
--- a/sys/pc98/pc98/npx.c
+++ b/sys/pc98/pc98/npx.c
@@ -44,11 +44,13 @@
#include <sys/bus.h>
#include <sys/ipl.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/proc.h>
#include <sys/mutex.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
#include <machine/bus.h>
#include <sys/rman.h>
#ifdef NPX_DEBUG
@@ -773,30 +775,41 @@ npx_intr(dummy)
u_short control;
struct intrframe *frame;
- mtx_lock(&Giant);
- if (PCPU_GET(npxproc) == NULL || !npx_exists) {
+ if (!npx_exists) {
printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n",
PCPU_GET(npxproc), curproc, npx_exists);
panic("npxintr from nowhere");
}
- if (PCPU_GET(npxproc) != curproc) {
- printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n",
- PCPU_GET(npxproc), curproc, npx_exists);
- panic("npxintr from non-current process");
- }
-
-#ifdef PC98
- outb(0xf8, 0);
+#ifdef PC98
+ outb(0xf8, 0);
#else
outb(0xf0, 0);
#endif
+ mtx_lock_spin(&sched_lock);
+ if (PCPU_GET(npxproc) != curproc) {
+ /*
+ * Interrupt handling (for this or another interrupt) has
+ * switched npxproc from underneath us before we managed
+ * to handle this interrupt. Just ignore this interrupt.
+ * Control will eventually return to the instruction that
+ * caused it and it will repeat. In the npx_ex16 case,
+ * then we will eventually (usually soon) win the race.
+ * In the npx_irq13 case, we will always lose the race
+ * because we have switched to the IRQ13 thread. This will
+ * be fixed later.
+ */
+ mtx_unlock_spin(&sched_lock);
+ return;
+ }
fnstsw(&PCPU_GET(curpcb)->pcb_savefpu.sv_ex_sw);
fnstcw(&control);
fnclex();
+ mtx_unlock_spin(&sched_lock);
/*
* Pass exception to process.
*/
+ mtx_lock(&Giant);
frame = (struct intrframe *)&dummy; /* XXX */
if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) {
/*