mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-23 01:51:58 +00:00
[pcbios] 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> Signed-off-by: Michael Brown <mcb30@etherboot.org>
This commit is contained in:
parent
dc387547a3
commit
f44205b9ea
@ -489,6 +489,18 @@ get_mangled_e820:
|
||||
ret
|
||||
.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
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -63,6 +63,8 @@ void fake_e820 ( void ) {
|
||||
"cmpl $0x534d4150, %%edx\n\t"
|
||||
"jne 99f\n\t"
|
||||
"pushaw\n\t"
|
||||
"movw %%sp, %%bp\n\t"
|
||||
"andb $~0x01, 22(%%bp)\n\t" /* Clear return CF */
|
||||
"leaw e820map(%%bx), %%si\n\t"
|
||||
"cs rep movsb\n\t"
|
||||
"popaw\n\t"
|
||||
@ -73,8 +75,7 @@ void fake_e820 ( void ) {
|
||||
"xorl %%ebx,%%ebx\n\t"
|
||||
"\n1:\n\t"
|
||||
"popfw\n\t"
|
||||
"clc\n\t"
|
||||
"lret $2\n\t"
|
||||
"iret\n\t"
|
||||
"\n99:\n\t"
|
||||
"popfw\n\t"
|
||||
"ljmp *%%cs:real_int15_vector\n\t" )
|
||||
|
@ -199,9 +199,12 @@ pxe_int_1a:
|
||||
shll $4, %edx
|
||||
addl $pxenv, %edx
|
||||
movw $0x564e, %ax
|
||||
pushw %bp
|
||||
movw %sp, %bp
|
||||
andb $~0x01, 8(%bp) /* Clear CF on return */
|
||||
popw %bp
|
||||
popfw
|
||||
clc
|
||||
lret $2
|
||||
iret
|
||||
1: /* INT 1A,other - pass through */
|
||||
popfw
|
||||
ljmp *%cs:pxe_int_1a_vector
|
||||
|
Loading…
Reference in New Issue
Block a user