aboutsummaryrefslogtreecommitdiffstats
path: root/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-04-14 21:52:50 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-04-14 21:52:50 -0700
commit51c8b419b201678ea27edfa9d037c851f18b7fb5 (patch)
tree566b8d74bcffd41fb392df83e8db28d77b4977f7 /gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
parent927a28f0f852b31950fd9d4f9d96049397d1eaa1 (diff)
downloadsyslinux.git-51c8b419b201678ea27edfa9d037c851f18b7fb5.tar.gz
syslinux.git-51c8b419b201678ea27edfa9d037c851f18b7fb5.tar.xz
syslinux.git-51c8b419b201678ea27edfa9d037c851f18b7fb5.zip
gpxe: Don't use "lret $2" to return from an interrupt
Using "lret $2" to return from an interrupt causes interrupts to be disabled in the calling program, since the INT instruction will have disabled interrupts. Instead, patch CF on the stack and use iret to return. Interestingly, the original PC BIOS had this bug in at least one place. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'gpxe/src/arch/i386/firmware/pcbios/e820mangler.S')
-rw-r--r--gpxe/src/arch/i386/firmware/pcbios/e820mangler.S27
1 files changed, 18 insertions, 9 deletions
diff --git a/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S b/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
index 4ba3fb14..decb0835 100644
--- a/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
+++ b/gpxe/src/arch/i386/firmware/pcbios/e820mangler.S
@@ -490,6 +490,18 @@ get_mangled_e820:
.size get_mangled_e820, . - get_mangled_e820
/****************************************************************************
+ * Set/clear CF on the stack as appropriate, assumes stack is as it should
+ * be immediately before IRET
+ ****************************************************************************
+ */
+patch_cf:
+ pushw %bp
+ movw %sp, %bp
+ setc 8(%bp) /* Set/reset CF; clears PF, AF, ZF, SF */
+ popw %bp
+ ret
+
+/****************************************************************************
* INT 15,e820 handler
****************************************************************************
*/
@@ -500,7 +512,8 @@ int15_e820:
popw %ds
call get_mangled_e820
popw %ds
- lret $2
+ call patch_cf
+ iret
.size int15_e820, . - int15_e820
/****************************************************************************
@@ -512,7 +525,7 @@ int15_e801:
/* Call previous handler */
pushfw
lcall *%cs:int15_vector
- pushfw
+ call patch_cf
/* Edit result */
pushw %ds
pushw %cs:rm_ds
@@ -524,9 +537,7 @@ int15_e801:
xchgw %ax, %cx
xchgw %bx, %dx
popw %ds
- /* Restore flags returned by previous handler and return */
- popfw
- lret $2
+ iret
.size int15_e801, . - int15_e801
/****************************************************************************
@@ -538,16 +549,14 @@ int15_88:
/* Call previous handler */
pushfw
lcall *%cs:int15_vector
- pushfw
+ call patch_cf
/* Edit result */
pushw %ds
pushw %cs:rm_ds
popw %ds
call patch_1m
popw %ds
- /* Restore flags returned by previous handler and return */
- popfw
- lret $2
+ iret
.size int15_88, . - int15_88
/****************************************************************************