diff options
Diffstat (limited to 'src/arch/x86/gdt_init.S')
-rw-r--r-- | src/arch/x86/gdt_init.S | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/arch/x86/gdt_init.S b/src/arch/x86/gdt_init.S index 7dd4b94933..1558ac62c8 100644 --- a/src/arch/x86/gdt_init.S +++ b/src/arch/x86/gdt_init.S @@ -20,7 +20,20 @@ gdtptr: .section ".text._gdt64_", "ax", @progbits .globl gdt_init64 gdt_init64: - lgdt gdtptr64 + /* Workaround a bug in the assembler. + * The following code doesn't work: + * lgdt gdtptr64 + * + * The assembler tries to save memory by using 32bit displacement addressing mode. + * Displacements are using signed integers. + * This is fine in protected mode, as the negative address points to the correct + * address > 2GiB, but in long mode this doesn't work at all. + * Tests showed that QEMU can gracefully handle it, but real CPUs can't. + * + * Use the movabs pseudo instruction to force using a 64bit absolute address. + */ + movabs $gdtptr64, %rax + lgdt (%rax) ret .previous |