core: pxe: don't switch to the PXE stack if we're on it...
authorH. Peter Anvin <hpa@zytor.com>
Fri, 11 Sep 2009 23:03:30 +0000 (16:03 -0700)
committerEric W. Biederman <ebiederm@xmission.com>
Tue, 12 Apr 2011 21:40:52 +0000 (14:40 -0700)
Don't switch to the PXE stack if we are already on it.  This can
happen if we take an interrupt inside the stack switch code.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
core/pxelinux.asm

index ab8526a..be304be 100644 (file)
@@ -375,9 +375,15 @@ pxenv:
                call timer_cleanup
 
 .store_stack:
+               pushf
+               cli
+               inc word [cs:PXEStackLock]
+               jnz .skip1
                mov [cs:PXEStack],sp
                mov [cs:PXEStack+2],ss
                lss sp,[cs:InitStack]
+.skip1:
+               popf
 
                ; Pre-clear the Status field
                mov word [es:di],cs
@@ -392,7 +398,13 @@ pxenv:
                add sp,6
                mov [cs:PXEStatus],ax
 
+               pushf
+               cli
+               dec word [cs:PXEStackLock]
+               jns .skip2
                lss sp,[cs:PXEStack]
+.skip2:
+               popf
 
                mov bp,sp
                and ax,ax
@@ -419,6 +431,16 @@ pxenv:
                 global PXEEntry
 PXEEntry       equ pxenv.jump+1
 
+;
+; The PXEStackLock keeps us from switching stacks if we take an interrupt
+; (which ends up calling pxenv) while we are already on the PXE stack.
+; It will be -1 normally, 0 inside a PXE call, and a positive value
+; inside a *nested* PXE call.
+;
+               section .data16
+               alignb 2
+PXEStackLock   dw -1
+
                section .bss16
                alignb 2
 PXEStatus      resb 2