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