diff --git a/hypervisor/arch/x86/boot/cpu_primary.S b/hypervisor/arch/x86/boot/cpu_primary.S index 11d08155c..bcc7117c6 100644 --- a/hypervisor/arch/x86/boot/cpu_primary.S +++ b/hypervisor/arch/x86/boot/cpu_primary.S @@ -65,8 +65,6 @@ 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 9cda53b01..3b2c31f08 100644 --- a/hypervisor/arch/x86/configs/vacpi.c +++ b/hypervisor/arch/x86/configs/vacpi.c @@ -5,24 +5,57 @@ */ #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) { - 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, - }; + 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); - 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); + 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); + } } diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index a7299b229..07684aae5 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -502,6 +502,7 @@ 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); @@ -526,6 +527,7 @@ 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,10 +868,6 @@ 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 45d2ab903..26a994106 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 */ -static struct acpi_table_rsdp *get_rsdp(void) +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 550563151..50bdd9d9a 100644 --- a/hypervisor/boot/include/acpi.h +++ b/hypervisor/boot/include/acpi.h @@ -237,6 +237,7 @@ 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 a0bb78b26..e2af3aae7 100644 --- a/hypervisor/boot/include/multiboot.h +++ b/hypervisor/boot/include/multiboot.h @@ -22,7 +22,6 @@ #ifndef ASSEMBLER -#include #include struct acrn_multiboot_info { @@ -43,7 +42,6 @@ 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 76cfb09d9..d8a284e59 100644 --- a/hypervisor/boot/include/multiboot_std.h +++ b/hypervisor/boot/include/multiboot_std.h @@ -209,19 +209,6 @@ 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 45cbcede4..9a0691c92 100644 --- a/hypervisor/boot/multiboot/multiboot.c +++ b/hypervisor/boot/multiboot/multiboot.c @@ -93,20 +93,6 @@ 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 e3611ac90..375b2196b 100644 --- a/hypervisor/boot/multiboot/multiboot2.c +++ b/hypervisor/boot/multiboot/multiboot2.c @@ -33,31 +33,6 @@ 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 */ @@ -91,12 +66,6 @@ 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 8d114816c..404de6ab7 100644 --- a/hypervisor/boot/multiboot/multiboot_priv.h +++ b/hypervisor/boot/multiboot/multiboot_priv.h @@ -7,10 +7,6 @@ #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 5e14dbedb..300c10052 100644 --- a/hypervisor/common/vm_load.c +++ b/hypervisor/common/vm_load.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -74,14 +75,8 @@ static uint64_t create_zero_page(struct acrn_vm *vm) /* clear the zeropage */ (void)memset(zeropage, 0U, MEM_2K); -#ifdef CONFIG_MULTIBOOT2 - if (is_sos_vm(vm)) { - struct acrn_multiboot_info *mbi = get_acrn_multiboot_info(); + zeropage->acpi_rsdp_addr = get_vrsdp_gpa(vm); - (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 746ce29ef..5efe8cf07 100644 --- a/hypervisor/include/arch/x86/zeropage.h +++ b/hypervisor/include/arch/x86/zeropage.h @@ -7,14 +7,13 @@ #ifndef ZEROPAGE_H #define ZEROPAGE_H #include -#include struct zero_page { - uint8_t pad0[0x1c0]; /* 0x000 */ + uint8_t pad0[0x70]; /* 0x000 */ - struct efi_info boot_efi_info; + uint64_t acpi_rsdp_addr; /* 0x070 */ - uint8_t pad1[0x8]; /* 0x1e0 */ + uint8_t pad1[0x170]; /* 0x78 */ 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 a5d57af8c..ebeaa3dcb 100644 --- a/hypervisor/include/dm/vacpi.h +++ b/hypervisor/include/dm/vacpi.h @@ -27,6 +27,7 @@ #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 deleted file mode 100644 index ab35da076..000000000 --- a/hypervisor/include/lib/efi.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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