aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-06-21 15:59:40 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-06-21 15:59:40 -0700
commit8659757a388ad9071156f2e3d6b04813960dcfed (patch)
treeae9298b7d98e67f900bff276598062589888d8c6
parent859ead0a2ef7dfd0b5622ad4878dda1b26c22e29 (diff)
downloadsyslinux-8659757a388ad9071156f2e3d6b04813960dcfed.tar.gz
syslinux-8659757a388ad9071156f2e3d6b04813960dcfed.tar.xz
syslinux-8659757a388ad9071156f2e3d6b04813960dcfed.zip
core: Make cfarcall IF-preserving
cfarcall does not take a register image on input, so we need to explicitly preserve IF in the code flow. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--core/callback.inc11
1 files changed, 9 insertions, 2 deletions
diff --git a/core/callback.inc b/core/callback.inc
index 6a351327..d98d8008 100644
--- a/core/callback.inc
+++ b/core/callback.inc
@@ -84,13 +84,15 @@ core_syscall:
bits 16
section .text16
.rm:
+ mov ax,sp
+ add ax,9*4+4*2
+ mov [CallbackSP],ax
pop gs
pop fs
pop es
pop ds
popad
popfd
- mov [cs:CallbackSP],sp
retf ; Invoke routine
.rm_return:
@@ -138,6 +140,7 @@ core_syscall:
;
; Cfarcall invocation. We copy the stack frame to the real-mode stack,
; followed by the return CS:IP and the CS:IP of the target function.
+; The value of IF is copied from the calling routine.
;
global core_cfarcall
core_cfarcall:
@@ -156,11 +159,14 @@ core_cfarcall:
mov [word CallbackSP],di
sub edi,ecx ; Allocate space for stack frame
and edi,~3 ; Round
- sub edi,4*2 ; Return pointer, return value
+ sub edi,4*3 ; Return pointer, return value, EFLAGS
mov [word RealModeSSSP],di
shl ebx,4
add edi,ebx ; Create linear address
+ mov eax,[esp+5*4] ; EFLAGS from entry
+ and eax,0x202 ; IF only
+ stosd
mov eax,[esp+7*4] ; CS:IP
stosd ; Save to stack frame
mov eax,.rm_return ; Return seg:off
@@ -179,6 +185,7 @@ core_cfarcall:
bits 16
section .text16
.rm:
+ popfd
retf
.rm_return:
mov sp,[cs:CallbackSP]