From c5e072432aac1a95a1f50b6778f835e89f181a1e Mon Sep 17 00:00:00 2001 From: Minggui Cao Date: Wed, 2 Jan 2019 16:01:10 +0800 Subject: [PATCH] HV: modularization to refine boot/bsp related code. 1. add static for local functions and variables. 2. move vm_sw_loader from vcpu to vm 3. refine uefi.c to follow the code rules. 4. separate uefi.c for vm0 boot and bsp two parts. bsp layer just access native HW related, can't access vm/vcpu, vm0 boot part can access vm / vcpu data structure. Tracked-On: #1842 Signed-off-by: Minggui Cao Reviewed-by: Jason Chen CJ --- hypervisor/Makefile | 1 + hypervisor/arch/x86/guest/vcpu.c | 2 - hypervisor/arch/x86/guest/vm.c | 5 + hypervisor/boot/dmar_parse.c | 2 +- hypervisor/boot/uefi/uefi_boot.c | 64 +++++++++++++ hypervisor/bsp/include/bsp_extern.h | 8 ++ hypervisor/bsp/uefi/uefi.c | 96 ++++++-------------- hypervisor/include/arch/x86/guest/vm0_boot.h | 3 +- 8 files changed, 110 insertions(+), 71 deletions(-) create mode 100644 hypervisor/boot/uefi/uefi_boot.c diff --git a/hypervisor/Makefile b/hypervisor/Makefile index dd71b8365..941c110fb 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -216,6 +216,7 @@ endif ifeq ($(CONFIG_PLATFORM_UEFI),y) C_SRCS += bsp/uefi/uefi.c C_SRCS += bsp/uefi/cmdline.c +C_SRCS += boot/uefi/uefi_boot.c TEMPLATE_ACPI_INFO_HEADER := bsp/include/uefi/platform_acpi_info.h else ifeq ($(CONFIG_PLATFORM_SBL),y) diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index 757565599..fbac84a3f 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -9,8 +9,6 @@ #include #include -vm_sw_loader_t vm_sw_loader; - inline uint64_t vcpu_get_gpreg(const struct acrn_vcpu *vcpu, uint32_t reg) { const struct run_context *ctx = diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index e1aa43122..d19348c06 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -9,6 +9,9 @@ #include #include #include +#include + +vm_sw_loader_t vm_sw_loader; /* Local variables */ @@ -101,6 +104,8 @@ int32_t create_vm(struct vm_description *vm_desc, struct acrn_vm **rtn_vm) #ifndef CONFIG_EFI_STUB status = init_vm_boot_info(vm); +#else + status = efi_boot_init(); #endif if (status == 0) { init_iommu_vm0_domain(vm); diff --git a/hypervisor/boot/dmar_parse.c b/hypervisor/boot/dmar_parse.c index 2f38c5d31..71323d7b3 100644 --- a/hypervisor/boot/dmar_parse.c +++ b/hypervisor/boot/dmar_parse.c @@ -291,7 +291,7 @@ handle_one_drhd(struct acpi_dmar_hardware_unit *acpi_drhd, return 0; } -int32_t parse_dmar_table(void) +static int32_t parse_dmar_table(void) { int32_t i; struct acpi_dmar_hardware_unit *acpi_drhd; diff --git a/hypervisor/boot/uefi/uefi_boot.c b/hypervisor/boot/uefi/uefi_boot.c new file mode 100644 index 000000000..93f864c20 --- /dev/null +++ b/hypervisor/boot/uefi/uefi_boot.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#ifdef CONFIG_EFI_STUB + +static void efi_spurious_handler(int32_t vector) +{ + if (get_cpu_id() == BOOT_CPU_ID) { + struct acrn_vcpu *vcpu = per_cpu(vcpu, BOOT_CPU_ID); + + if (vcpu != NULL) { + vlapic_set_intr(vcpu, vector, 0); + } else { + pr_err("%s vcpu or vlapic is not ready, interrupt lost\n", __func__); + } + } +} + +static int32_t uefi_sw_loader(struct acrn_vm *vm) +{ + int32_t ret = 0; + struct acrn_vcpu *vcpu = get_primary_vcpu(vm); + struct acrn_vcpu_regs *vcpu_regs = &boot_context; + const struct efi_context *efi_ctx = get_efi_ctx(); + const struct lapic_regs *uefi_lapic_regs = get_efi_lapic_regs(); + + pr_dbg("Loading guest to run-time location"); + + vlapic_restore(vcpu_vlapic(vcpu), uefi_lapic_regs); + + /* For UEFI platform, the bsp init regs come from two places: + * 1. saved in efi_boot: gpregs, rip + * 2. saved when HV started: other registers + * We copy the info saved in efi_boot to boot_context and + * init bsp with boot_context. + */ + memcpy_s(&(vcpu_regs->gprs), sizeof(struct acrn_gp_regs), + &(efi_ctx->vcpu_regs.gprs), sizeof(struct acrn_gp_regs)); + + vcpu_regs->rip = efi_ctx->vcpu_regs.rip; + set_vcpu_regs(vcpu, vcpu_regs); + + /* defer irq enabling till vlapic is ready */ + CPU_IRQ_ENABLE(); + + return ret; +} + +int32_t efi_boot_init(void) +{ + vm_sw_loader = uefi_sw_loader; + spurious_handler = (spurious_handler_t)efi_spurious_handler; + + return 0; +} +#endif diff --git a/hypervisor/bsp/include/bsp_extern.h b/hypervisor/bsp/include/bsp_extern.h index f7ffd679f..2c0f08469 100644 --- a/hypervisor/bsp/include/bsp_extern.h +++ b/hypervisor/bsp/include/bsp_extern.h @@ -40,4 +40,12 @@ void init_bsp(void); void acpi_fixup(void); #endif +#ifdef CONFIG_EFI_STUB + +void *get_rsdp_from_uefi(void); +void *get_ap_trampoline_buf(void); +const struct efi_context *get_efi_ctx(void); +const struct lapic_regs *get_efi_lapic_regs(void); +#endif + #endif /* BSP_EXTERN_H */ diff --git a/hypervisor/bsp/uefi/uefi.c b/hypervisor/bsp/uefi/uefi.c index 2c3217e83..e69843243 100644 --- a/hypervisor/bsp/uefi/uefi.c +++ b/hypervisor/bsp/uefi/uefi.c @@ -10,63 +10,41 @@ #include #ifdef CONFIG_EFI_STUB -static void efi_init(void); -struct efi_context* efi_ctx = NULL; -struct lapic_regs uefi_lapic_regs; +static struct efi_context *efi_ctx = NULL; +static struct lapic_regs uefi_lapic_regs; static int32_t efi_initialized; -void efi_spurious_handler(int32_t vector) +static void efi_init(void) { - struct acrn_vcpu* vcpu; + struct multiboot_info *mbi = NULL; - if (get_cpu_id() != 0) - return; + if (boot_regs[0] != MULTIBOOT_INFO_MAGIC) { + pr_err("no multiboot info found"); + } else { - vcpu = per_cpu(vcpu, 0); - if (vcpu != NULL) { - vlapic_set_intr(vcpu, vector, 0); - } else - pr_err("%s vcpu or vlapic is not ready, interrupt lost\n", - __func__); + mbi = (struct multiboot_info *) hpa2hva(((uint64_t)(uint32_t)boot_regs[1])); + if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_DRIVES) == 0U) { + pr_err("no multiboot drivers for uefi found"); + } else { - return; -} + efi_ctx = (struct efi_context *)hpa2hva((uint64_t)mbi->mi_drives_addr); + if (efi_ctx == NULL) { + pr_err("no uefi context found"); + } else { -int32_t uefi_sw_loader(struct acrn_vm *vm) -{ - int32_t ret = 0; - struct acrn_vcpu *vcpu = get_primary_vcpu(vm); - struct acrn_vcpu_regs *vcpu_regs = &boot_context; - - ASSERT(vm != NULL, "Incorrect argument"); - - pr_dbg("Loading guest to run-time location"); - - vlapic_restore(vcpu_vlapic(vcpu), &uefi_lapic_regs); - - /* For UEFI platform, the bsp init regs come from two places: - * 1. saved in efi_boot: gpregs, rip - * 2. saved when HV started: other registers - * We copy the info saved in efi_boot to boot_context and - * init bsp with boot_context. - */ - memcpy_s(&(vcpu_regs->gprs), sizeof(struct acrn_gp_regs), - &(efi_ctx->vcpu_regs.gprs), sizeof(struct acrn_gp_regs)); - - vcpu_regs->rip = efi_ctx->vcpu_regs.rip; - set_vcpu_regs(vcpu, vcpu_regs); - - /* defer irq enabling till vlapic is ready */ - CPU_IRQ_ENABLE(); - - return ret; + save_lapic(&uefi_lapic_regs); + efi_initialized = 1; + } + } + } } void *get_rsdp_from_uefi(void) { - if (!efi_initialized) + if (!efi_initialized) { efi_init(); + } return hpa2hva((uint64_t)efi_ctx->rsdp); } @@ -76,30 +54,16 @@ void *get_ap_trampoline_buf(void) return efi_ctx->ap_trampoline_buf; } -static void efi_init(void) +const struct efi_context *get_efi_ctx(void) { - struct multiboot_info *mbi = NULL; - - if (boot_regs[0] != MULTIBOOT_INFO_MAGIC) - ASSERT(0, "no multiboot info found"); - - mbi = (struct multiboot_info *) - hpa2hva(((uint64_t)(uint32_t)boot_regs[1])); - - if (!(mbi->mi_flags & MULTIBOOT_INFO_HAS_DRIVES)) - ASSERT(0, "no multiboot drivers for uefi found"); - - efi_ctx = (struct efi_context *)hpa2hva((uint64_t)mbi->mi_drives_addr); - ASSERT(efi_ctx != NULL, "no uefi context found"); - - vm_sw_loader = uefi_sw_loader; - - spurious_handler = (spurious_handler_t)efi_spurious_handler; - - save_lapic(&uefi_lapic_regs); - - efi_initialized = 1; + return efi_ctx; } + +const struct lapic_regs *get_efi_lapic_regs(void) +{ + return &uefi_lapic_regs; +} + #endif void init_bsp(void) diff --git a/hypervisor/include/arch/x86/guest/vm0_boot.h b/hypervisor/include/arch/x86/guest/vm0_boot.h index 27ef6e60e..e41ec0ba4 100644 --- a/hypervisor/include/arch/x86/guest/vm0_boot.h +++ b/hypervisor/include/arch/x86/guest/vm0_boot.h @@ -14,8 +14,7 @@ struct efi_context { void *ap_trampoline_buf; } __packed; -void *get_rsdp_from_uefi(void); -void *get_ap_trampoline_buf(void); +int32_t efi_boot_init(void); #endif #endif /* VM0_BOOT_H */