[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |