From 3fee32c0bb0ef702132e1738266f5df0d4d72ce3 Mon Sep 17 00:00:00 2001 From: Chaohong guo Date: Wed, 16 Jan 2019 14:00:17 +0800 Subject: [PATCH] EFI: Allocate EFI boot related struct from EFI allocation pool Current EFI boot related structs are allocated right after HV binary, and marked as EfiResered. In fact, the memory should be reclaimed and managed by HV once EFI boot is done, Moreover, HV is doing 2M alignment, which is overwriting this allocated memory. This patch is to allocate EFI info from EFI allocation pool and marked as EFiloaderdata, so that the memory is used by HV, also, it will reduce the fragmentation. Tracked-On: #2035 Signed-off-by: Chaohong guo Reviewed-by: Eddie Dong --- efi-stub/boot.c | 46 ++++++++++++++++++++++------------------------ efi-stub/boot.h | 14 +++++++------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/efi-stub/boot.c b/efi-stub/boot.c index e2666f8c7..bc0cdc5ac 100644 --- a/efi-stub/boot.c +++ b/efi-stub/boot.c @@ -67,24 +67,16 @@ static inline void hv_jump(EFI_PHYSICAL_ADDRESS hv_start, hf(MULTIBOOT_INFO_MAGIC, mbi); } -EFI_STATUS construct_mbi(EFI_PHYSICAL_ADDRESS hv_hpa) +EFI_STATUS construct_mbi(EFI_PHYSICAL_ADDRESS hv_hpa, struct multiboot_info *mbi, + struct multiboot_mmap *mmap) { UINTN map_size, map_key; UINT32 desc_version; UINTN desc_size; EFI_MEMORY_DESCRIPTOR *map_buf; EFI_STATUS err = EFI_SUCCESS; - struct multiboot_info *mbi; - struct multiboot_mmap *mmap; - struct efi_context *efi_ctx; int32_t i, j; - mbi = MBOOT_INFO_PTR(hv_hpa); - mmap = MBOOT_MMAP_PTR(hv_hpa); - efi_ctx = BOOT_CTX_PTR(hv_hpa); - (void)memset((void *)mbi, 0x0, MBOOT_INFO_SIZE); - (void)memset((void *)mmap, 0x0, MBOOT_MMAP_SIZE); - /* We're just interested in the map's size for now */ map_size = 0; err = get_memory_map(&map_size, NULL, NULL, NULL, NULL); @@ -177,19 +169,14 @@ again: * available RAM in e820 table */ mmap[j].mm_base_addr = hv_hpa; - mmap[j].mm_length = HV_RUNTIME_MEM_SIZE; + mmap[j].mm_length = CONFIG_HV_RAM_SIZE; mmap[j].mm_type = E820_RAM; j++; - mbi->mi_flags |= MULTIBOOT_INFO_HAS_MMAP | MULTIBOOT_INFO_HAS_CMDLINE; - mbi->mi_mmap_length = j*sizeof(struct multiboot_mmap); - mbi->mi_cmdline = (UINTN)cmdline; mbi->mi_mmap_addr = (UINTN)mmap; - - mbi->mi_flags |= MULTIBOOT_INFO_HAS_DRIVES; - mbi->mi_drives_addr = (UINT32)(UINTN)efi_ctx; - + mbi->mi_mmap_length = j*sizeof(struct multiboot_mmap); + mbi->mi_flags |= MULTIBOOT_INFO_HAS_MMAP | MULTIBOOT_INFO_HAS_CMDLINE; out: return err; } @@ -199,15 +186,23 @@ switch_to_guest_mode(EFI_HANDLE image, EFI_PHYSICAL_ADDRESS hv_hpa) { EFI_PHYSICAL_ADDRESS addr; EFI_STATUS err; + struct multiboot_mmap *mmap; struct multiboot_info *mbi; struct efi_context *efi_ctx; struct acpi_table_rsdp *rsdp = NULL; int32_t i; EFI_CONFIGURATION_TABLE *config_table; - mbi = MBOOT_INFO_PTR(hv_hpa); - efi_ctx = BOOT_CTX_PTR(hv_hpa); - (void)memset((void *)efi_ctx, 0x0, BOOT_CTX_SIZE); + err = allocate_pool(EfiLoaderData, EFI_BOOT_MEM_SIZE, (VOID *)&addr); + if (err != EFI_SUCCESS) { + Print(L"Failed to allocate memory for EFI boot\n"); + goto out; + } + (void)memset((void *)addr, 0x0, EFI_BOOT_MEM_SIZE); + + mmap = MBOOT_MMAP_PTR(addr); + mbi = MBOOT_INFO_PTR(addr); + efi_ctx = BOOT_CTX_PTR(addr); /* reserve secondary memory region for CPU trampoline code */ err = emalloc_reserved_mem(&addr, CONFIG_LOW_RAM_SIZE, MEM_ADDR_1MB); @@ -245,10 +240,13 @@ switch_to_guest_mode(EFI_HANDLE image, EFI_PHYSICAL_ADDRESS hv_hpa) efi_ctx->rsdp = rsdp; /* construct multiboot info and deliver it to hypervisor */ - err = construct_mbi(hv_hpa); + err = construct_mbi(hv_hpa, mbi, mmap); if (err != EFI_SUCCESS) goto out; + mbi->mi_flags |= MULTIBOOT_INFO_HAS_DRIVES; + mbi->mi_drives_addr = (UINT32)(UINTN)efi_ctx; + asm volatile ("pushf\n\t" "pop %0\n\t" : "=r"(efi_ctx->vcpu_regs.rflags) @@ -363,9 +361,9 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) * instead. */ #ifdef CONFIG_RELOC - err = emalloc_reserved_aligned(&hv_hpa, HV_RUNTIME_MEM_SIZE, 1 << 21, MEM_ADDR_4GB); + err = emalloc_reserved_aligned(&hv_hpa, CONFIG_HV_RAM_SIZE, 1 << 21, MEM_ADDR_4GB); #else - err = emalloc_fixed_addr(&hv_hpa, HV_RUNTIME_MEM_SIZE, CONFIG_HV_RAM_START); + err = emalloc_fixed_addr(&hv_hpa, CONFIG_HV_RAM_SIZE, CONFIG_HV_RAM_START); #endif if (err != EFI_SUCCESS) goto failed; diff --git a/efi-stub/boot.h b/efi-stub/boot.h index d1c5f29dd..86ac9f667 100644 --- a/efi-stub/boot.h +++ b/efi-stub/boot.h @@ -77,14 +77,14 @@ typedef void(*hv_func)(int32_t, struct multiboot_info*); #define MBOOT_MMAP_SIZE (sizeof(struct multiboot_mmap) * MBOOT_MMAP_NUMS) #define MBOOT_INFO_SIZE (sizeof(struct multiboot_info)) #define BOOT_CTX_SIZE (sizeof(struct efi_context)) -#define HV_RUNTIME_MEM_SIZE \ - (CONFIG_HV_RAM_SIZE + MBOOT_MMAP_SIZE + MBOOT_INFO_SIZE + BOOT_CTX_SIZE) +#define EFI_BOOT_MEM_SIZE \ + (MBOOT_MMAP_SIZE + MBOOT_INFO_SIZE + BOOT_CTX_SIZE) #define MBOOT_MMAP_PTR(addr) \ - ((struct multiboot_mmap *)((VOID *)addr + CONFIG_HV_RAM_SIZE)) -#define MBOOT_INFO_PTR(addr) ((struct multiboot_info *) \ - ((VOID *)addr + CONFIG_HV_RAM_SIZE + MBOOT_MMAP_SIZE)) -#define BOOT_CTX_PTR(addr) ((struct efi_context *) \ - ((VOID *)addr + CONFIG_HV_RAM_SIZE + MBOOT_MMAP_SIZE + MBOOT_INFO_SIZE)) + ((struct multiboot_mmap *)((VOID *)(addr))) +#define MBOOT_INFO_PTR(addr) \ + ((struct multiboot_info *)((VOID *)(addr) + MBOOT_MMAP_SIZE)) +#define BOOT_CTX_PTR(addr) \ + ((struct efi_context *)((VOID *)(addr) + MBOOT_MMAP_SIZE + MBOOT_INFO_SIZE)) struct efi_info {