summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2004-07-10 14:21:41 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2004-07-10 14:21:41 +0000
commitc4662898f8a5504d906d7e13522818a4aea8d0dd (patch)
treedfe5726ecd0a0e3309161255fa07b7aae41c4f32 /sys
parentdf85339a5d0f61f8da868668f60c6c049875f9fa (diff)
From NetBSD:
date: 2004/06/28 09:13:11; author: fvdl; state: Exp; lines: +6 -5 Updaing ci_ilevel and testing ci_ipending must be done with all interrupts off, or priority inversion can occur, which can lead to IPI deadlocks. Leaves interrupts off for a bit longer, sadly, but with no noticeable effects on the systems I tested on. From YAMAMOTO Takashi. Fixes the IPI rendezvous panics for me.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/intr.c21
-rw-r--r--sys/arch/amd64/amd64/spl.S6
-rw-r--r--sys/arch/amd64/amd64/vector.S13
3 files changed, 21 insertions, 19 deletions
diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c
index 5f605a9e642..63c199e55dd 100644
--- a/sys/arch/amd64/amd64/intr.c
+++ b/sys/arch/amd64/amd64/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.5 2004/06/28 02:14:11 deraadt Exp $ */
+/* $OpenBSD: intr.c,v 1.6 2004/07/10 14:21:40 art Exp $ */
/* $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $ */
/*
@@ -52,6 +52,7 @@
#include <machine/i8259.h>
#include <machine/cpu.h>
#include <machine/pio.h>
+#include <machine/cpufunc.h>
#include "ioapic.h"
#include "lapic.h"
@@ -734,17 +735,21 @@ spllower(int nlevel)
{
int olevel;
struct cpu_info *ci = curcpu();
+ u_int32_t imask;
+ u_long psl;
- /*
- * Since this should only lower the interrupt level,
- * the XOR below should only show interrupts that
- * are being unmasked.
- */
+ imask = IUNMASK(ci, nlevel);
olevel = ci->ci_ilevel;
- if (ci->ci_ipending & IUNMASK(ci,nlevel))
+
+ psl = read_psl();
+ disable_intr();
+
+ if (ci->ci_ipending & imask) {
Xspllower(nlevel);
- else
+ } else {
ci->ci_ilevel = nlevel;
+ write_psl(psl);
+ }
return (olevel);
}
diff --git a/sys/arch/amd64/amd64/spl.S b/sys/arch/amd64/amd64/spl.S
index 7772f14205b..aa3be7b6e5f 100644
--- a/sys/arch/amd64/amd64/spl.S
+++ b/sys/arch/amd64/amd64/spl.S
@@ -1,4 +1,4 @@
-/* $NetBSD: spl.S,v 1.1 2003/04/26 18:39:32 fvdl Exp $ */
+/* $NetBSD: spl.S,v 1.3 2004/06/28 09:13:11 fvdl Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -132,10 +132,8 @@ IDTVEC(spllower)
cli
andl CPUVAR(IPENDING),%eax # any non-masked bits left?
jz 2f
- sti
bsrl %eax,%eax
btrl %eax,CPUVAR(IPENDING)
- jnc 1b
movq CPUVAR(ISOURCES)(,%rax,8),%rax
jmp *IS_RECURSE(%rax)
2:
@@ -162,10 +160,8 @@ IDTVEC(doreti)
cli
andl CPUVAR(IPENDING),%eax
jz 2f
- sti
bsrl %eax,%eax # slow, but not worth optimizing
btrl %eax,CPUVAR(IPENDING)
- jnc 1b # some intr cleared the in-memory bit
movq CPUVAR(ISOURCES)(,%rax, 8),%rax
jmp *IS_RESUME(%rax)
2: /* Check for ASTs on exit to user mode. */
diff --git a/sys/arch/amd64/amd64/vector.S b/sys/arch/amd64/amd64/vector.S
index db35fbd1edd..e269c7f60ae 100644
--- a/sys/arch/amd64/amd64/vector.S
+++ b/sys/arch/amd64/amd64/vector.S
@@ -1,5 +1,5 @@
-/* $OpenBSD: vector.S,v 1.4 2004/06/28 01:52:24 deraadt Exp $ */
-/* $NetBSD: vector.S,v 1.2 2003/05/04 23:46:41 fvdl Exp $ */
+/* $OpenBSD: vector.S,v 1.5 2004/07/10 14:21:40 art Exp $ */
+/* $NetBSD: vector.S,v 1.5 2004/06/28 09:13:11 fvdl Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -296,8 +296,6 @@ IDTVEC(recurse_lapic_ipi)
pushq $0
pushq $T_ASTFLT
INTRENTRY
-IDTVEC(resume_lapic_ipi)
- cli
jmp 1f
IDTVEC(intr_lapic_ipi)
pushq $0
@@ -307,6 +305,7 @@ IDTVEC(intr_lapic_ipi)
movl CPUVAR(ILEVEL),%ebx
cmpl $IPL_IPI,%ebx
jae 2f
+IDTVEC(resume_lapic_ipi)
1:
incl CPUVAR(IDEPTH)
movl $IPL_IPI,CPUVAR(ILEVEL)
@@ -329,8 +328,6 @@ IDTVEC(recurse_lapic_ltimer)
pushq $0
pushq $T_ASTFLT
INTRENTRY
-IDTVEC(resume_lapic_ltimer)
- cli
jmp 1f
IDTVEC(intr_lapic_ltimer)
pushq $0
@@ -340,6 +337,7 @@ IDTVEC(intr_lapic_ltimer)
movl CPUVAR(ILEVEL),%ebx
cmpl $IPL_CLOCK,%ebx
jae 2f
+IDTVEC(resume_lapic_ltimer)
1:
incl CPUVAR(IDEPTH)
movl $IPL_CLOCK,CPUVAR(ILEVEL)
@@ -750,6 +748,7 @@ _C_LABEL(netisr):
IDTVEC(softserial)
movl $IPL_SOFTSERIAL, CPUVAR(ILEVEL)
+ sti
incl CPUVAR(IDEPTH)
#ifdef MULTIPROCESSOR
call _C_LABEL(x86_softintlock)
@@ -766,6 +765,7 @@ IDTVEC(softserial)
IDTVEC(softnet)
movl $IPL_SOFTNET, CPUVAR(ILEVEL)
+ sti
incl CPUVAR(IDEPTH)
#ifdef MULTIPROCESSOR
call _C_LABEL(x86_softintlock)
@@ -795,6 +795,7 @@ IDTVEC(softnet)
IDTVEC(softclock)
movl $IPL_SOFTCLOCK, CPUVAR(ILEVEL)
+ sti
incl CPUVAR(IDEPTH)
#ifdef MULTIPROCESSOR
call _C_LABEL(x86_softintlock)