From 28824c1e749398d985f5ef651d13e7a19b17c0e1 Mon Sep 17 00:00:00 2001 From: Victor Sun Date: Wed, 22 Sep 2021 10:28:33 +0800 Subject: [PATCH] HV: init e820 before init paging In the commit of 4e1deab3d9fbb7ba80e9c6c4cb8e785df33888b1, we changed the init sequence that init paging first and then init e820 because we worried about the efi memory map could be beyond 4GB space on some platform. After we double checked multiboot2 spec, when system boot from multiboot2 protocol, the efi memory map info will be embedded in multiboot info so it is guaranteed that the efi memory map must be under 4GB space. Consider that the page table will be allocated in free memory space in future, we have to change the init sequence back that init e820 first and then init paging. If we need to support other boot protocol in future that the efi memory map might be put beyond 4GB, we could have below options: 1. Request bootloader put efi memory map below 4GB; 2. Call EFI_BOOT_SERVICES.GetMemoryMap() before ExitBootServices(); 3. Enable a early 64bit page table to get the efi memory map only; Tracked-On: #5626 Signed-off-by: Victor Sun --- hypervisor/arch/x86/cpu.c | 3 ++- hypervisor/boot/boot.c | 4 ++-- hypervisor/boot/multiboot/multiboot2.c | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index bcbeb6d6e..2218f0b1b 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -156,9 +156,10 @@ void init_pcpu_pre(bool is_bsp) load_pcpu_state_data(); + init_e820(); + /* Initialize the hypervisor paging */ init_paging(); - init_e820(); /* * Need update uart_base_address here for vaddr2paddr mapping may changed diff --git a/hypervisor/boot/boot.c b/hypervisor/boot/boot.c index 1b9fa0313..49cd7e5d2 100644 --- a/hypervisor/boot/boot.c +++ b/hypervisor/boot/boot.c @@ -55,8 +55,8 @@ int32_t sanitize_acrn_boot_info(struct acrn_boot_info *abi) } printf("%s environment detected.\n", boot_from_uefi(abi) ? "UEFI" : "Non-UEFI"); - if (boot_from_uefi(abi) && (abi->uefi_info.memmap == 0U) && (abi->uefi_info.memmap_hi == 0U)) { - pr_err("no efi memmap found!"); + if (boot_from_uefi(abi) && ((abi->uefi_info.memmap == 0U) || (abi->uefi_info.memmap_hi != 0U))) { + pr_err("no efi memmap found below 4GB space!"); abi_status = -EINVAL; } diff --git a/hypervisor/boot/multiboot/multiboot2.c b/hypervisor/boot/multiboot/multiboot2.c index 3149326d4..d502cf514 100644 --- a/hypervisor/boot/multiboot/multiboot2.c +++ b/hypervisor/boot/multiboot/multiboot2.c @@ -66,6 +66,7 @@ static void mb2_efimmap_to_abi(struct acrn_boot_info *abi, abi->uefi_info.memdesc_version = mb2_tag_efimmap->descr_vers; abi->uefi_info.memmap = (uint32_t)(uint64_t)mb2_tag_efimmap->efi_mmap; abi->uefi_info.memmap_size = mb2_tag_efimmap->size - 16U; + /* Per multiboot2 spec, multiboot info is below 4GB space hence memmap_hi must be 0U. */ abi->uefi_info.memmap_hi = (uint32_t)(((uint64_t)mb2_tag_efimmap->efi_mmap) >> 32U); }