]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[pcbios] Don't use "lret $2" to return from an interrupt
authorH. Peter Anvin <hpa@zytor.com>
Sun, 12 Apr 2009 01:30:22 +0000 (18:30 -0700)
committerMichael Brown <mcb30@etherboot.org>
Wed, 15 Apr 2009 14:45:27 +0000 (15:45 +0100)
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>
src/arch/i386/firmware/pcbios/e820mangler.S
src/arch/i386/firmware/pcbios/fakee820.c
src/arch/i386/interface/pxe/pxe_entry.S

index 4ba3fb14141af2fd6b5162d7f02a3a66657eb21f..decb083569733c37cdc536e2f72392e949a7b9fb 100644 (file)
@@ -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
                
 /****************************************************************************
index e171edfd62e69c7cefd68cf02fc9c4a6ed97d444..552bf41d2d53442df851d4703022b10317c168c0 100644 (file)
@@ -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" )
index 22ef41814ddeba25479e65ef9277b9938bf52342..0e8c8e2d63846edab0db75c7d89703f438362ab1 100644 (file)
@@ -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