HV: Revert "HV: remove efi support for SOS"

This reverts commit ce9d5e8779.

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 <victor.sun@intel.com>
This commit is contained in:
Victor Sun 2021-03-14 22:13:47 +08:00 committed by wenlingz
parent 95f38ac12e
commit 8483c8c8f7
14 changed files with 114 additions and 54 deletions

View File

@ -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

View File

@ -5,57 +5,24 @@
*/
#include <vm.h>
#include <mmu.h>
#include <ept.h>
#include <vacpi.h>
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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -22,6 +22,7 @@
#ifndef ASSEMBLER
#include <efi.h>
#include <vm_configurations.h>
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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -10,7 +10,6 @@
#include <ept.h>
#include <mmu.h>
#include <multiboot.h>
#include <vacpi.h>
#include <errno.h>
#include <sprintf.h>
#include <logmsg.h>
@ -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),

View File

@ -7,13 +7,14 @@
#ifndef ZEROPAGE_H
#define ZEROPAGE_H
#include <e820.h>
#include <efi.h>
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 */

View File

@ -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 */

View File

@ -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