From 5a5b2a1eadb2075a9efd9e069492ffc28d1d7169 Mon Sep 17 00:00:00 2001 From: Binbin Wu Date: Sat, 28 Jul 2018 13:50:58 +0800 Subject: [PATCH] hv: init: save boot context from bootloader/bios Add code to save boot context, which is prepare by the bootloader or BIOS, the context can be used to init sos vmcs, such as GDT, IDT, segment selectors, control registers, ia32_efer. In this way, HV can leverage the data structures built by bootloader or BIOS, without creating them in HV. Signed-off-by: Binbin Wu Reviewed-by: Eddie Dong Reviewed-by: Jason Chen CJ --- hypervisor/Makefile | 1 + hypervisor/arch/x86/cpu_primary.S | 20 +++-- hypervisor/arch/x86/cpu_save_boot_ctx.S | 98 +++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 hypervisor/arch/x86/cpu_save_boot_ctx.S diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 0101b191a..f574d1256 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -122,6 +122,7 @@ C_SRCS += arch/x86/notify.c C_SRCS += arch/x86/vtd.c C_SRCS += arch/x86/gdt.c S_SRCS += arch/x86/cpu_primary.S +S_SRCS += arch/x86/cpu_save_boot_ctx.S S_SRCS += arch/x86/idt.S C_SRCS += arch/x86/irq.c C_SRCS += arch/x86/timer.c diff --git a/hypervisor/arch/x86/cpu_primary.S b/hypervisor/arch/x86/cpu_primary.S index a4440b4ee..becfd22d2 100644 --- a/hypervisor/arch/x86/cpu_primary.S +++ b/hypervisor/arch/x86/cpu_primary.S @@ -31,6 +31,8 @@ #define MULTIBOOT_HEADER_MAGIC 0x1badb002 #define MULTIBOOT_HEADER_FLAGS 0x00000002 /*flags bit 1 : enable mem_*, mmap_**/ + .extern cpu_primary_save32 + .extern cpu_primary_save64 .section multiboot_header, "a" .align 4 @@ -49,16 +51,19 @@ .global cpu_primary_start_32 cpu_primary_start_32: + /* save the MULTBOOT magic number & MBI */ + movl %eax, (boot_regs) + movl %ebx, (boot_regs+4) + + /* Save boot context from 32bit mode */ + call cpu_primary_save_32 + /* Disable interrupts */ cli /* Clear direction flag */ cld - /* save eax and ebx */ - movl %eax, %esp - movl %ebx, %ebp - /* detect whether it is in long mode * * 0xc0000080 = MSR_IA32_EFER @@ -71,10 +76,6 @@ cpu_primary_start_32: /* jump to 64bit entry if it is already in long mode */ jne cpu_primary_start_64 - /* save the MULTBOOT magic number & MBI */ - movl %esp, (boot_regs) - movl %ebp, (boot_regs+4) - /* Disable paging */ mov %cr0, %ebx /* 0x7fffffff = ~CR0_PG */ @@ -124,6 +125,9 @@ cpu_primary_start_64: movl %edi, (%rax) movl %esi, 4(%rax) + /* Save boot context from 64bit mode */ + call cpu_primary_save_64 + primary_start_long_mode: /* Initialize temporary stack pointer */ diff --git a/hypervisor/arch/x86/cpu_save_boot_ctx.S b/hypervisor/arch/x86/cpu_save_boot_ctx.S new file mode 100644 index 000000000..c7b7be227 --- /dev/null +++ b/hypervisor/arch/x86/cpu_save_boot_ctx.S @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define BOOT_CTX_CR0_OFFSET 0 +#define BOOT_CTX_CR3_OFFSET 8 +#define BOOT_CTX_CR4_OFFSET 16 +#define BOOT_CTX_IDT_OFFSET 24 +#define BOOT_CTX_GDT_OFFSET 34 +#define BOOT_CTX_LDT_SEL_OFFSET 44 +#define BOOT_CTX_TR_SEL_OFFSET 46 +#define BOOT_CTX_CS_SEL_OFFSET 48 +#define BOOT_CTX_SS_SEL_OFFSET 50 +#define BOOT_CTX_DS_SEL_OFFSET 52 +#define BOOT_CTX_ES_SEL_OFFSET 54 +#define BOOT_CTX_FS_SEL_OFFSET 56 +#define BOOT_CTX_GS_SEL_OFFSET 58 +#define BOOT_CTX_CS_AR_OFFSET 60 +#define BOOT_CTX_EFER_LOW_OFFSET 64 +#define BOOT_CTX_EFER_HIGH_OFFSET 68 + + .section entry, "ax" + .align 8 + .code32 + + .global cpu_primary_save_32 +cpu_primary_save_32: + /* save context from 32bit mode */ + lea vm0_boot_context, %eax + sgdt BOOT_CTX_GDT_OFFSET(%eax) + sidt BOOT_CTX_IDT_OFFSET(%eax) + str BOOT_CTX_TR_SEL_OFFSET(%eax) + sldt BOOT_CTX_LDT_SEL_OFFSET(%eax) + movl %cr0, %ecx + movl %ecx, BOOT_CTX_CR0_OFFSET(%eax) + movl %cr3, %ecx + movl %ecx, BOOT_CTX_CR3_OFFSET(%eax) + movl %cr4, %ecx + movl %ecx, BOOT_CTX_CR4_OFFSET(%eax) + mov %cs, %cx + mov %cx, BOOT_CTX_CS_SEL_OFFSET(%eax) + lar %ecx, %ecx + /* CS AR start from bit 8 */ + shr $8, %ecx + /* Clear Limit field, bit 8-11 */ + andl $0x0000f0ff, %ecx + mov %ecx, BOOT_CTX_CS_AR_OFFSET(%eax) + mov %es, BOOT_CTX_ES_SEL_OFFSET(%eax) + mov %ss, BOOT_CTX_SS_SEL_OFFSET(%eax) + mov %ds, BOOT_CTX_DS_SEL_OFFSET(%eax) + mov %fs, BOOT_CTX_FS_SEL_OFFSET(%eax) + mov %gs, BOOT_CTX_GS_SEL_OFFSET(%eax) + ret + + .code64 + .global cpu_primary_save_64 +cpu_primary_save_64: + /* save context from 64bit mode */ + lea vm0_boot_context(%rip), %r8 + sgdt BOOT_CTX_GDT_OFFSET(%r8) + sidt BOOT_CTX_IDT_OFFSET(%r8) + str BOOT_CTX_TR_SEL_OFFSET(%r8) + sldt BOOT_CTX_LDT_SEL_OFFSET(%r8) + mov %cr0, %rcx + mov %rcx, BOOT_CTX_CR0_OFFSET(%r8) + mov %cr3, %rcx + mov %rcx, BOOT_CTX_CR3_OFFSET(%r8) + mov %cr4, %rcx + mov %rcx, BOOT_CTX_CR4_OFFSET(%r8) + mov %cs, %cx + mov %cx, BOOT_CTX_CS_SEL_OFFSET(%r8) + lar %ecx, %ecx + /* CS AR start from bit 8 */ + shr $8, %ecx + /* Clear Limit field, bit 8-11 */ + andl $0x0000f0ff, %ecx + mov %ecx, BOOT_CTX_CS_AR_OFFSET(%r8) + mov %es, BOOT_CTX_ES_SEL_OFFSET(%r8) + mov %ss, BOOT_CTX_SS_SEL_OFFSET(%r8) + mov %ds, BOOT_CTX_DS_SEL_OFFSET(%r8) + mov %fs, BOOT_CTX_FS_SEL_OFFSET(%r8) + mov %gs, BOOT_CTX_GS_SEL_OFFSET(%r8) + /* 0xc0000080 = MSR_IA32_EFER */ + movl $0xc0000080, %ecx + rdmsr + movl %eax, BOOT_CTX_EFER_LOW_OFFSET(%r8) + movl %edx, BOOT_CTX_EFER_HIGH_OFFSET(%r8) + ret + + .text + .align 8 + .global vm0_boot_context +vm0_boot_context: + .rept 9 + .quad 0x0000000000000000 + .endr