From 8483c8c8f7ea48827f5a2722d3e1f9b8fd3c5fd9 Mon Sep 17 00:00:00 2001 From: Victor Sun Date: Sun, 14 Mar 2021 22:13:47 +0800 Subject: [PATCH] HV: Revert "HV: remove efi support for SOS" This reverts commit ce9d5e87791cfd135de8cd997274e2e03c75f5a1. Before readiness of better solution to fix SOS VM e820 and efi memmap mismatch issue, revert this patch. Tracked-On: #5626 Signed-off-by: Victor Sun --- hypervisor/arch/x86/boot/cpu_primary.S | 2 + hypervisor/arch/x86/configs/vacpi.c | 55 +++++----------------- hypervisor/arch/x86/guest/vm.c | 6 ++- hypervisor/boot/acpi_base.c | 2 +- hypervisor/boot/include/acpi.h | 1 - hypervisor/boot/include/multiboot.h | 2 + hypervisor/boot/include/multiboot_std.h | 13 +++++ hypervisor/boot/multiboot/multiboot.c | 14 ++++++ hypervisor/boot/multiboot/multiboot2.c | 31 ++++++++++++ hypervisor/boot/multiboot/multiboot_priv.h | 4 ++ hypervisor/common/vm_load.c | 9 +++- hypervisor/include/arch/x86/zeropage.h | 7 +-- hypervisor/include/dm/vacpi.h | 1 - hypervisor/include/lib/efi.h | 21 +++++++++ 14 files changed, 114 insertions(+), 54 deletions(-) create mode 100644 hypervisor/include/lib/efi.h diff --git a/hypervisor/arch/x86/boot/cpu_primary.S b/hypervisor/arch/x86/boot/cpu_primary.S index bcc7117c6..11d08155c 100644 --- a/hypervisor/arch/x86/boot/cpu_primary.S +++ b/hypervisor/arch/x86/boot/cpu_primary.S @@ -65,6 +65,8 @@ info_req_tag_start: .long MULTIBOOT2_TAG_TYPE_MMAP /* memory map */ .long MULTIBOOT2_TAG_TYPE_MODULE /* boot modules infomation */ .long MULTIBOOT2_TAG_TYPE_ACPI_NEW /* a copy of RSDP as defined per ACPI 2.0 or later specification */ + .long MULTIBOOT2_TAG_TYPE_EFI64 /* EFI system table, to be passed to guest Linux */ + .long MULTIBOOT2_TAG_TYPE_EFI_MMAP /* EFI memory map, to be passed to guest Linux */ info_req_tag_end: #ifdef CONFIG_RELOC diff --git a/hypervisor/arch/x86/configs/vacpi.c b/hypervisor/arch/x86/configs/vacpi.c index 3b2c31f08..9cda53b01 100644 --- a/hypervisor/arch/x86/configs/vacpi.c +++ b/hypervisor/arch/x86/configs/vacpi.c @@ -5,57 +5,24 @@ */ #include -#include -#include #include -static uint64_t sos_rsdp_gpa; - -uint64_t get_vrsdp_gpa(struct acrn_vm *vm) -{ - uint64_t gpa = 0UL; - - if (is_sos_vm(vm)) { - gpa = sos_rsdp_gpa; - } else if (is_prelaunched_vm(vm)) { - gpa = VIRT_RSDP_ADDR; - } - return gpa; -} - /** * @pre vm != NULL * @pre vm->vm_id < CONFIG_MAX_VM_NUM */ void build_vrsdp(struct acrn_vm *vm) { - if (is_sos_vm(vm)) { - /* Reserve a memory area from host e820 space to store SOS VM ACPI RSDP info. - * This should be done before create_sos_vm_e820() because the SOS e820 - * need to be updated from host e820 table accordingly. - */ - uint64_t sos_rsdp_hpa = e820_alloc_memory(MEM_1K, MEM_2G * 2); + struct acpi_table_rsdp rsdp = { + .signature = ACPI_SIG_RSDP, + .oem_id = ACPI_OEM_ID, + .revision = 0x2U, + .length = ACPI_RSDP_XCHECKSUM_LENGTH, + .xsdt_physical_address = VIRT_XSDT_ADDR, + }; - stac(); - (void)memcpy_s(hpa2hva(sos_rsdp_hpa), sizeof(struct acpi_table_rsdp), - get_rsdp(), sizeof(struct acpi_table_rsdp)); - clac(); - sos_rsdp_gpa = sos_vm_hpa2gpa(sos_rsdp_hpa); - - } else if (is_prelaunched_vm(vm)) { - struct acpi_table_rsdp rsdp = { - .signature = ACPI_SIG_RSDP, - .oem_id = ACPI_OEM_ID, - .revision = 0x2U, - .length = ACPI_RSDP_XCHECKSUM_LENGTH, - .xsdt_physical_address = VIRT_XSDT_ADDR, - }; - - rsdp.checksum = calculate_checksum8(&rsdp, ACPI_RSDP_CHECKSUM_LENGTH); - rsdp.extended_checksum = calculate_checksum8(&rsdp, ACPI_RSDP_XCHECKSUM_LENGTH); - /* Copy RSDP table to guest physical memory F segment - * This should be done after prepare_prelaunched_vm_memmap() - */ - (void)copy_to_gpa(vm, &rsdp, VIRT_RSDP_ADDR, ACPI_RSDP_XCHECKSUM_LENGTH); - } + rsdp.checksum = calculate_checksum8(&rsdp, ACPI_RSDP_CHECKSUM_LENGTH); + rsdp.extended_checksum = calculate_checksum8(&rsdp, ACPI_RSDP_XCHECKSUM_LENGTH); + /* Copy RSDP table to guest physical memory F segment */ + (void)copy_to_gpa(vm, &rsdp, VIRT_RSDP_ADDR, ACPI_RSDP_XCHECKSUM_LENGTH); } diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 31f58a62b..5e020b800 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -501,7 +501,6 @@ int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *v if (is_sos_vm(vm)) { /* Only for SOS_VM */ - build_vrsdp(vm); create_sos_vm_e820(vm); prepare_sos_vm_memmap(vm); @@ -524,7 +523,6 @@ int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *v if (vm_config->load_order == PRE_LAUNCHED_VM) { create_prelaunched_vm_e820(vm); prepare_prelaunched_vm_memmap(vm, vm_config); - build_vrsdp(vm); status = init_vm_boot_info(vm); } } @@ -866,6 +864,10 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config) err = create_vm(vm_id, vm_config->cpu_affinity, vm_config, &vm); if (err == 0) { + if (is_prelaunched_vm(vm)) { + build_vrsdp(vm); + } + (void)vm_sw_loader(vm); /* start vm BSP automatically */ diff --git a/hypervisor/boot/acpi_base.c b/hypervisor/boot/acpi_base.c index 26a994106..45d2ab903 100644 --- a/hypervisor/boot/acpi_base.c +++ b/hypervisor/boot/acpi_base.c @@ -62,7 +62,7 @@ static struct acpi_table_rsdp *found_rsdp(char *base, uint64_t length) /* RSDP parsed from BIOS region should exist. * If it is NULL, the hypervisor can't be booted */ -struct acpi_table_rsdp *get_rsdp(void) +static struct acpi_table_rsdp *get_rsdp(void) { return acpi_rsdp; } diff --git a/hypervisor/boot/include/acpi.h b/hypervisor/boot/include/acpi.h index 50bdd9d9a..550563151 100644 --- a/hypervisor/boot/include/acpi.h +++ b/hypervisor/boot/include/acpi.h @@ -237,7 +237,6 @@ struct acpi_table_tpm2 { } __packed; void init_acpi(void); -struct acpi_table_rsdp *get_rsdp(void); void *get_acpi_tbl(const char *signature); struct ioapic_info; diff --git a/hypervisor/boot/include/multiboot.h b/hypervisor/boot/include/multiboot.h index e2af3aae7..a0bb78b26 100644 --- a/hypervisor/boot/include/multiboot.h +++ b/hypervisor/boot/include/multiboot.h @@ -22,6 +22,7 @@ #ifndef ASSEMBLER +#include #include struct acrn_multiboot_info { @@ -42,6 +43,7 @@ struct acrn_multiboot_info { struct multiboot_mmap mi_mmap_entry[MAX_MMAP_ENTRIES]; const void *mi_acpi_rsdp_va; + struct efi_info mi_efi_info; }; void init_acrn_multiboot_info(uint32_t magic, uint32_t info); diff --git a/hypervisor/boot/include/multiboot_std.h b/hypervisor/boot/include/multiboot_std.h index d8a284e59..76cfb09d9 100644 --- a/hypervisor/boot/include/multiboot_std.h +++ b/hypervisor/boot/include/multiboot_std.h @@ -209,6 +209,19 @@ struct multiboot2_tag_new_acpi { uint8_t rsdp[0]; }; +struct multiboot2_tag_efi64 { + uint32_t type; + uint32_t size; + uint64_t pointer; +}; + +struct multiboot2_tag_efi_mmap { + uint32_t type; + uint32_t size; + uint32_t descr_size; + uint32_t descr_vers; + uint8_t efi_mmap[0]; +}; #endif #endif /* CONFIG_MULTIBOOT2 */ diff --git a/hypervisor/boot/multiboot/multiboot.c b/hypervisor/boot/multiboot/multiboot.c index 9a0691c92..45cbcede4 100644 --- a/hypervisor/boot/multiboot/multiboot.c +++ b/hypervisor/boot/multiboot/multiboot.c @@ -93,6 +93,20 @@ int32_t sanitize_acrn_multiboot_info(uint32_t magic, uint32_t info) mbi_status = -EINVAL; } +#ifdef CONFIG_MULTIBOOT2 + if (boot_from_multiboot2(magic)) { + if (acrn_mbi.mi_efi_info.efi_memmap_hi != 0U) { + pr_err("the EFI mmap address should be less than 4G!"); + acrn_mbi.mi_flags &= ~MULTIBOOT_INFO_HAS_EFI_MMAP; + mbi_status = -EINVAL; + } + + if ((acrn_mbi.mi_flags & (MULTIBOOT_INFO_HAS_EFI64 | MULTIBOOT_INFO_HAS_EFI_MMAP)) == 0U) { + pr_err("no multiboot2 uefi info found!"); + } + } +#endif + if (acrn_mbi.mi_loader_name[0] == '\0') { pr_err("no bootloader name found!"); mbi_status = -EINVAL; diff --git a/hypervisor/boot/multiboot/multiboot2.c b/hypervisor/boot/multiboot/multiboot2.c index 375b2196b..e3611ac90 100644 --- a/hypervisor/boot/multiboot/multiboot2.c +++ b/hypervisor/boot/multiboot/multiboot2.c @@ -33,6 +33,31 @@ static void mb2_mods_to_mbi(struct acrn_multiboot_info *mbi, } } +/** + * @pre mbi != NULL && mb2_tag_efi64 != 0 + */ +static void mb2_efi64_to_mbi(struct acrn_multiboot_info *mbi, const struct multiboot2_tag_efi64 *mb2_tag_efi64) +{ + const uint32_t efiloader_sig = 0x34364c45; /* "EL64" */ + mbi->mi_efi_info.efi_systab = (uint32_t)(uint64_t)mb2_tag_efi64->pointer; + mbi->mi_efi_info.efi_loader_signature = efiloader_sig; + mbi->mi_flags |= MULTIBOOT_INFO_HAS_EFI64; +} + +/** + * @pre mbi != NULL && mb2_tag_efimmap != 0 + */ +static void mb2_efimmap_to_mbi(struct acrn_multiboot_info *mbi, + const struct multiboot2_tag_efi_mmap *mb2_tag_efimmap) +{ + mbi->mi_efi_info.efi_memdesc_size = mb2_tag_efimmap->descr_size; + mbi->mi_efi_info.efi_memdesc_version = mb2_tag_efimmap->descr_vers; + mbi->mi_efi_info.efi_memmap = (uint32_t)(uint64_t)mb2_tag_efimmap->efi_mmap; + mbi->mi_efi_info.efi_memmap_size = mb2_tag_efimmap->size - 16U; + mbi->mi_efi_info.efi_memmap_hi = (uint32_t)(((uint64_t)mb2_tag_efimmap->efi_mmap) >> 32U); + mbi->mi_flags |= MULTIBOOT_INFO_HAS_EFI_MMAP; +} + /** * @pre mbi != NULL */ @@ -66,6 +91,12 @@ int32_t multiboot2_to_acrn_mbi(struct acrn_multiboot_info *mbi, void *mb2_info) case MULTIBOOT2_TAG_TYPE_ACPI_NEW: mbi->mi_acpi_rsdp_va = ((struct multiboot2_tag_new_acpi *)mb2_tag)->rsdp; break; + case MULTIBOOT2_TAG_TYPE_EFI64: + mb2_efi64_to_mbi(mbi, (const struct multiboot2_tag_efi64 *)mb2_tag); + break; + case MULTIBOOT2_TAG_TYPE_EFI_MMAP: + mb2_efimmap_to_mbi(mbi, (const struct multiboot2_tag_efi_mmap *)mb2_tag); + break; default: if (mb2_tag->type > MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR) { ret = -EINVAL; diff --git a/hypervisor/boot/multiboot/multiboot_priv.h b/hypervisor/boot/multiboot/multiboot_priv.h index 404de6ab7..8d114816c 100644 --- a/hypervisor/boot/multiboot/multiboot_priv.h +++ b/hypervisor/boot/multiboot/multiboot_priv.h @@ -7,6 +7,10 @@ #ifndef MULTIBOOT_PRIV_H #define MULTIBOOT_PRIV_H +/* extended flags for acrn multiboot info from multiboot2 */ +#define MULTIBOOT_INFO_HAS_EFI_MMAP 0x00010000U +#define MULTIBOOT_INFO_HAS_EFI64 0x00020000U + #ifdef CONFIG_MULTIBOOT2 /* * @post boot_regs[1] stores the address pointer that point to a valid multiboot2 info diff --git a/hypervisor/common/vm_load.c b/hypervisor/common/vm_load.c index 300c10052..5e14dbedb 100644 --- a/hypervisor/common/vm_load.c +++ b/hypervisor/common/vm_load.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -75,8 +74,14 @@ static uint64_t create_zero_page(struct acrn_vm *vm) /* clear the zeropage */ (void)memset(zeropage, 0U, MEM_2K); - zeropage->acpi_rsdp_addr = get_vrsdp_gpa(vm); +#ifdef CONFIG_MULTIBOOT2 + if (is_sos_vm(vm)) { + struct acrn_multiboot_info *mbi = get_acrn_multiboot_info(); + (void)memcpy_s(&(zeropage->boot_efi_info), sizeof(zeropage->boot_efi_info), + &(mbi->mi_efi_info), sizeof(mbi->mi_efi_info)); + } +#endif /* copy part of the header into the zero page */ hva = (struct zero_page *)gpa2hva(vm, (uint64_t)sw_kernel->kernel_load_addr); (void)memcpy_s(&(zeropage->hdr), sizeof(zeropage->hdr), diff --git a/hypervisor/include/arch/x86/zeropage.h b/hypervisor/include/arch/x86/zeropage.h index 5efe8cf07..746ce29ef 100644 --- a/hypervisor/include/arch/x86/zeropage.h +++ b/hypervisor/include/arch/x86/zeropage.h @@ -7,13 +7,14 @@ #ifndef ZEROPAGE_H #define ZEROPAGE_H #include +#include struct zero_page { - uint8_t pad0[0x70]; /* 0x000 */ + uint8_t pad0[0x1c0]; /* 0x000 */ - uint64_t acpi_rsdp_addr; /* 0x070 */ + struct efi_info boot_efi_info; - uint8_t pad1[0x170]; /* 0x78 */ + uint8_t pad1[0x8]; /* 0x1e0 */ uint8_t e820_nentries; /* 0x1e8 */ uint8_t pad2[0x8]; /* 0x1e9 */ diff --git a/hypervisor/include/dm/vacpi.h b/hypervisor/include/dm/vacpi.h index ebeaa3dcb..a5d57af8c 100644 --- a/hypervisor/include/dm/vacpi.h +++ b/hypervisor/include/dm/vacpi.h @@ -27,7 +27,6 @@ #define UOS_VIRT_PCI_MMCFG_START_BUS 0x0U #define UOS_VIRT_PCI_MMCFG_END_BUS 0xFFU -uint64_t get_vrsdp_gpa(struct acrn_vm *vm); void build_vrsdp(struct acrn_vm *vm); #endif /* VACPI_H */ diff --git a/hypervisor/include/lib/efi.h b/hypervisor/include/lib/efi.h new file mode 100644 index 000000000..ab35da076 --- /dev/null +++ b/hypervisor/include/lib/efi.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EFI_H +#define EFI_H + +struct efi_info { + uint32_t efi_loader_signature; /* 0x1c0 */ + uint32_t efi_systab; /* 0x1c4 */ + uint32_t efi_memdesc_size; /* 0x1c8 */ + uint32_t efi_memdesc_version; /* 0x1cc */ + uint32_t efi_memmap; /* 0x1d0 */ + uint32_t efi_memmap_size; /* 0x1d4 */ + uint32_t efi_systab_hi; /* 0x1d8 */ + uint32_t efi_memmap_hi; /* 0x1dc */ +} __packed; + +#endif