[i386] Add data32 prefixes to all lgdt/lidt instructions
authorMichael Brown <mcb30@etherboot.org>
Thu, 6 Nov 2008 23:08:10 +0000 (23:08 +0000)
committerMichael Brown <mcb30@etherboot.org>
Fri, 7 Nov 2008 03:48:25 +0000 (03:48 +0000)
With a 16-bit operand, lgdt/lidt will load only a 24-bit base address,
ignoring the high-order bits.  This meant that we could fail to fully
restore the GDT across a call into gPXE, if the GDT happened to be
located above the 16MB mark.

Not all of our lgdt/lidt instructions require a data32 prefix (for
example, reloading the real-mode IDT can never require a 32-bit base
address), but by adding them everywhere we will hopefully not forget
the necessary ones in future.

src/arch/i386/prefix/libprefix.S
src/arch/i386/transitions/librm.S

index 7159d74..6154961 100644 (file)
@@ -341,7 +341,7 @@ pm_call:
        /* Switch CPU to protected mode and load up segment registers */
        pushl   %eax
        cli
-       lgdt    PM_CALL_VAR(gdt)(%bp)
+       data32 lgdt PM_CALL_VAR(gdt)(%bp)
        movl    %cr0, %eax
        orb     $CR0_PE, %al
        movl    %eax, %cr0
@@ -377,7 +377,7 @@ pm_call:
        popw    %es
        popw    %fs
        popw    %gs
-       lgdt    PM_CALL_VAR(pm_saved_gdt)(%bp)
+       data32 lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
        popfl
        movw    %bp, %sp
        popw    %bp
index ff4b1d9..7e9fd45 100755 (executable)
@@ -203,8 +203,8 @@ real_to_prot:
 
        /* Switch to protected mode */
        cli
-       data32 lgdt     gdtr
-       data32 lidt     idtr
+       data32 lgdt gdtr
+       data32 lidt idtr
        movl    %cr0, %eax
        orb     $CR0_PE, %al
        movl    %eax, %cr0
@@ -316,7 +316,7 @@ p2r_jump_target:
        movl    %edx, %esp
 
        /* Reset IDTR to the real-mode defaults */
-       lidt    rm_idtr
+       data32 lidt rm_idtr
 
        /* Return to real-mode address */
        data32 ret
@@ -424,8 +424,8 @@ prot_call:
 1:     
        /* Reload GDT and IDT, restore registers and flags and return */
        movw    %sp, %bp
-       lgdt    (%bp)
-       lidt    8(%bp)
+       data32 lgdt (%bp)
+       data32 lidt 8(%bp)
        addw    $20, %sp /* also skip %cs and %ss */
        popw    %ds
        popw    %es