[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 3/4] plat/kvm: streamline protected mode early boot code



Multiboot drops us into protected mode with a suitable set of segment
register settings [1], so in fact all the GDT and segment register setup
is superfluous, considering this code relies on being reached from
multiboot anyway. Minimize _libkvmplat_start32 to do only what we really
care about: get out of protected mode and into long mode as fast as
possible.

Instead, do the GDT and segment register setup early in
_libkvmplat_start64. This removes the reliance of the long mode boot
code on initialization done in the protected mode code, which has the
beneficial side effect that hypervisors that drop us off in long mode
already (looking at you, Firecracker) can just use _libkvmplat_start64
as their entry point.

[1] 
https://www.gnu.org/software/grub/manual/multiboot/html_node/Machine-state.html

Signed-off-by: Florian Schmidt <florian.schmidt@xxxxxxxxx>
---
 plat/kvm/x86/entry64.S | 53 +++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/plat/kvm/x86/entry64.S b/plat/kvm/x86/entry64.S
index 7647446d..8abc8efb 100644
--- a/plat/kvm/x86/entry64.S
+++ b/plat/kvm/x86/entry64.S
@@ -68,29 +68,15 @@ bootstack:
 
 ENTRY(_libkvmplat_start32)
        cld
-       movl $bootstack, %esp
-
-       /* save multiboot info pointer at top of stack, we pop it in 64bit */
-       pushl $0
-       pushl %ebx
 
        /* only multiboot is supported for now */
        cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax
        jne nomultiboot
 
-       lgdt (gdt64_ptr)
-
-       movl $(gdt64_ds-gdt64), %eax
-       movl %eax, %ds
-       movl %eax, %es
-       movl %eax, %ss
-
-       xorl %eax, %eax
-       movl %eax, %fs
-       movl %eax, %gs
-
        /*
-        * x86_64 switch to long mode
+        * Multiboot drops us off in 32-bit protected mode with some sane
+        * initial settings, good enough to go straight for the only thing
+        * that we care about: go straight into long mode..
         */
 
        /* 1: enable pae */
@@ -113,12 +99,7 @@ ENTRY(_libkvmplat_start32)
        orl $X86_CR0_PG, %eax
        movl %eax, %cr0
 
-       /* 5: poetically longjump to longmode,
-        *    letting lret set %cs to the correct GDT entry on the way
-        */
-       pushl $(gdt64_cs-gdt64)
-       pushl $_libkvmplat_start64
-       lret
+       jmp _libkvmplat_start64
 
        /* NOTREACHED */
        jmp haltme
@@ -168,9 +149,33 @@ mxcsr_ptr:
 .section .text.boot
 
 ENTRY(_libkvmplat_start64)
+       /* set up the boot stack */
        movq $bootstack, %rsp
        xorq %rbp, %rbp
 
+       lgdt (gdt64_ptr)
+       /* let lret jump just one instruction ahead, but set %cs
+        * to the correect GDT entry while doing that.
+        */
+       pushq $(gdt64_cs-gdt64)
+       pushq $1f
+       lretq
+1:
+       /* Set up the remaining segment registers */
+       movq $(gdt64_ds-gdt64), %rax
+       movq %rax, %ds
+       movq %rax, %es
+       movq %rax, %ss
+       xorq %rax, %rax
+       movq %rax, %fs
+       movq %rax, %gs
+
+       /* Multiboot gives us a pointer to its mutliboot information in ebx.
+        * However, we need that for cpuid, so push it here and then
+        * and pop it back at the end.
+        */
+       pushq %rbx
+
        /* We will work on cr0 and cr4 multiple times.
         * We put cr0 into rsi and cr4 into rdi, because cpuid and
         * xgetbv/xsetbv work on eax/ebx/ecx/edx. */
@@ -224,7 +229,7 @@ nofsgsbase:
        /* done setting up CPU capabilities */
 
        /* read multiboot info pointer */
-       movq -8(%rsp), %rdi
+       popq %rdi
 
        pushq $0x0
        pushq $0x0
-- 
2.21.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.