summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/apic_ipl.s
diff options
context:
space:
mode:
authorfsmp <fsmp@FreeBSD.org>1997-07-23 21:25:31 +0000
committerfsmp <fsmp@FreeBSD.org>1997-07-23 21:25:31 +0000
commit68126f0545f0f9b21238e8dea11e4a4893f19334 (patch)
treedc502d34f922b049a8db02c0f7cdfa528566337d /sys/i386/isa/apic_ipl.s
parent181a3aef05fad102fcb087cc47240b3a5d52298e (diff)
downloadFreeBSD-src-68126f0545f0f9b21238e8dea11e4a4893f19334.zip
FreeBSD-src-68126f0545f0f9b21238e8dea11e4a4893f19334.tar.gz
Fixed possible deadlock from recursive INTs on same cpu. Since
we use lazy masking INTREN()/INTRDIS() might be called with INTs enabled. This means another higher prio INT to the same cpu could attempt to re-enter the critical region, but would spin waiting for the lock. Since it is the owner, it would deadlock.
Diffstat (limited to 'sys/i386/isa/apic_ipl.s')
-rw-r--r--sys/i386/isa/apic_ipl.s12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/i386/isa/apic_ipl.s b/sys/i386/isa/apic_ipl.s
index d11a6ea..c065aa3 100644
--- a/sys/i386/isa/apic_ipl.s
+++ b/sys/i386/isa/apic_ipl.s
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: apic_ipl.s,v 1.18 1997/07/23 20:18:14 smp Exp smp $
+ * $Id: apic_ipl.s,v 1.19 1997/07/23 21:18:30 smp Exp smp $
*/
@@ -254,9 +254,11 @@ bad_mask: .asciz "bad mask"
ALIGN_TEXT
.globl _INTREN
_INTREN:
+ pushfl /* save state of EI flag */
+ cli /* prevent recursion */
IMASK_LOCK /* enter critical reg */
- movl 4(%esp), %eax /* mask into %eax */
+ movl 8(%esp), %eax /* mask into %eax */
bsfl %eax, %ecx /* get pin index */
btrl %ecx, _apic_imen /* update _apic_imen */
@@ -273,6 +275,7 @@ _INTREN:
movl %eax, 16(%edx) /* write the APIC register data */
IMASK_UNLOCK /* exit critical reg */
+ popfl /* restore old state of EI flag */
ret
/*
@@ -285,9 +288,11 @@ _INTREN:
ALIGN_TEXT
.globl _INTRDIS
_INTRDIS:
+ pushfl /* save state of EI flag */
+ cli /* prevent recursion */
IMASK_LOCK /* enter critical reg */
- movl 4(%esp), %eax /* mask into %eax */
+ movl 8(%esp), %eax /* mask into %eax */
bsfl %eax, %ecx /* get pin index */
btsl %ecx, _apic_imen /* update _apic_imen */
@@ -304,6 +309,7 @@ _INTRDIS:
movl %eax, 16(%edx) /* write the APIC register data */
IMASK_UNLOCK /* exit critical reg */
+ popfl /* restore old state of EI flag */
ret
OpenPOWER on IntegriCloud