diff options
author | Michael Brown <mcb30@etherboot.org> | 2008-11-06 23:08:10 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2008-11-07 03:48:25 +0000 |
commit | 29e6f9835ea0277c262b1ab2c4acee1d69cb7099 (patch) | |
tree | ba53b2dcc7d2fd841ede1773a4cc3ac186a26524 | |
parent | aa95744915aba1b96fd226609e07ad1843437afc (diff) | |
download | ipxe-29e6f9835ea0277c262b1ab2c4acee1d69cb7099.tar.gz |
[i386] Add data32 prefixes to all lgdt/lidt instructions
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.
-rw-r--r-- | src/arch/i386/prefix/libprefix.S | 4 | ||||
-rwxr-xr-x | src/arch/i386/transitions/librm.S | 10 |
2 files changed, 7 insertions, 7 deletions
diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index 7159d745e..61549618a 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -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 diff --git a/src/arch/i386/transitions/librm.S b/src/arch/i386/transitions/librm.S index ff4b1d978..7e9fd45d4 100755 --- a/src/arch/i386/transitions/librm.S +++ b/src/arch/i386/transitions/librm.S @@ -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 |