diff options
author | fsmp <fsmp@FreeBSD.org> | 1997-07-23 21:25:31 +0000 |
---|---|---|
committer | fsmp <fsmp@FreeBSD.org> | 1997-07-23 21:25:31 +0000 |
commit | 68126f0545f0f9b21238e8dea11e4a4893f19334 (patch) | |
tree | dc502d34f922b049a8db02c0f7cdfa528566337d /sys/i386/isa/apic_ipl.s | |
parent | 181a3aef05fad102fcb087cc47240b3a5d52298e (diff) | |
download | FreeBSD-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.s | 12 |
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 |