From 6c9e451b41ad92ae3b32a30776fdf0ebdc3c51e1 Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Fri, 22 Jun 2018 09:02:49 -0700 Subject: [PATCH] hv: EFI can load Hypervisor to address other than COMNFIG_RAM_START - UEFI: change __emalloc() function to allocate from any available memory under 4G - Define CONFIG_RAM_START to the lowest possible address 1M, making sure HV can only be relocated to higher address Signed-off-by: Zheng Gen Signed-off-by: Zide Chen Reviewed-by: Yin fengwei --- hypervisor/arch/x86/Kconfig | 2 +- hypervisor/bsp/uefi/efi/boot.c | 13 +++--- hypervisor/bsp/uefi/efi/malloc.c | 54 ++++++++++------------- hypervisor/bsp/uefi/include/bsp/bsp_cfg.h | 7 ++- 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index 80a2c89a4..81f683719 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -94,7 +94,7 @@ config LOW_RAM_SIZE config RAM_START hex "Address of the RAM region assigned to the hypervisor" default 0x6e000000 if PLATFORM_SBL - default 0x20000000 if PLATFORM_UEFI + default 0x00100000 if PLATFORM_UEFI config RAM_SIZE hex "Size of the RAM region assigned to the hypervisor" diff --git a/hypervisor/bsp/uefi/efi/boot.c b/hypervisor/bsp/uefi/efi/boot.c index 6628bef68..fef1bb152 100644 --- a/hypervisor/bsp/uefi/efi/boot.c +++ b/hypervisor/bsp/uefi/efi/boot.c @@ -41,6 +41,7 @@ EFI_SYSTEM_TABLE *sys_table; EFI_BOOT_SERVICES *boot; char *cmdline = NULL; extern const uint64_t guest_entry; +static UINT64 hv_hpa; static inline void hv_jump(EFI_PHYSICAL_ADDRESS hv_start, struct multiboot_info *mbi, struct efi_ctx *efi_ctx) @@ -185,7 +186,7 @@ again: /* switch hv memory region(0x20000000 ~ 0x22000000) to * available RAM in e820 table */ - mmap[j].mm_base_addr = CONFIG_RAM_START; + mmap[j].mm_base_addr = hv_hpa; mmap[j].mm_length = CONFIG_RAM_SIZE; mmap[j].mm_type = E820_RAM; j++; @@ -307,7 +308,7 @@ switch_to_guest_mode(EFI_HANDLE image) asm volatile ("movq %%r14, %0" : "=r"(efi_ctx->r14)); asm volatile ("movq %%r15, %0" : "=r"(efi_ctx->r15)); - hv_jump(CONFIG_RAM_START, mbi, efi_ctx); + hv_jump(hv_hpa, mbi, efi_ctx); asm volatile (".global guest_entry\n\t" "guest_entry:\n\t"); @@ -331,7 +332,6 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) WCHAR *error_buf; EFI_STATUS err; EFI_LOADED_IMAGE *info; - EFI_PHYSICAL_ADDRESS addr; UINTN sec_addr; UINTN sec_size; char *section; @@ -393,13 +393,12 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) goto failed; } - err = __emalloc(CONFIG_RAM_SIZE, CONFIG_RAM_START, &addr, - EfiReservedMemoryType); + err = __emalloc(CONFIG_RAM_SIZE, CONFIG_RAM_START, &hv_hpa, + EfiReservedMemoryType); if (err != EFI_SUCCESS) goto failed; - /* Copy ACRNHV binary to fixed phys addr. LoadImage and StartImage ?? */ - memcpy((char*)addr, info->ImageBase + sec_addr, sec_size); + memcpy((char *)hv_hpa, info->ImageBase + sec_addr, sec_size); /* load hypervisor and begin to run on it */ err = switch_to_guest_mode(image); diff --git a/hypervisor/bsp/uefi/efi/malloc.c b/hypervisor/bsp/uefi/efi/malloc.c index 0a9a23bf1..3e161347d 100644 --- a/hypervisor/bsp/uefi/efi/malloc.c +++ b/hypervisor/bsp/uefi/efi/malloc.c @@ -223,11 +223,7 @@ fail: return err; } -/* FIXME: This function cannot guarantee to return address under 4G, - * and the hypervisor cannot handle params, which address is above 4G, - * delivered from efi stub. - */ -EFI_STATUS __emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr, +EFI_STATUS __emalloc(UINTN size, UINTN min_addr, EFI_PHYSICAL_ADDRESS *addr, EFI_MEMORY_TYPE mem_type) { UINTN map_size, map_key, desc_size; @@ -244,48 +240,46 @@ EFI_STATUS __emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr, d = (UINTN)map_buf; map_end = (UINTN)map_buf + map_size; + size = nr_pages << EFI_PAGE_SHIFT; for (; d < map_end; d += desc_size) { EFI_MEMORY_DESCRIPTOR *desc; EFI_PHYSICAL_ADDRESS start, end, aligned; desc = (EFI_MEMORY_DESCRIPTOR *)d; - if (desc->Type != EfiConventionalMemory) - continue; - - if (desc->NumberOfPages < nr_pages) - continue; - start = desc->PhysicalStart; end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT); - /* Low-memory is super-precious! */ - if (end <= 1 << 20) - continue; - if (start < 1 << 20) { - size -= (1 << 20) - start; - start = (1 << 20); + if ((min_addr > start) && (min_addr < end)) { + start = min_addr; } - aligned = align;//(start + align -1) & ~(align -1); + start = (start + EFI_PAGE_SIZE - 1) & ~(EFI_PAGE_SIZE - 1); + /* + * Low-memory is super-precious! + * Also we don't allocate from address over 4G + */ + if ((desc->Type != EfiConventionalMemory) || + (desc->NumberOfPages < nr_pages) || + (start < (1ULL << 20)) || + ((start + size) > end) || + ((start + size) >= (1UL << 32))) { + continue; + } - if ((aligned + size) <= end) { - //Print(L"trying to allocate memory at %0x!\n", aligned); - err = allocate_pages(AllocateAddress, mem_type, - nr_pages, &aligned); - if (err == EFI_SUCCESS) { - //Print(L"trying to allocate memory at %0x, success!\n", aligned); - *addr = aligned; - break; - } { - //Print(L"trying to allocate memory at %0x, failure!\n", aligned); - } + aligned = start; + err = allocate_pages(AllocateAddress, mem_type, + nr_pages, &aligned); + if (err == EFI_SUCCESS) { + *addr = aligned; + break; } } - if (d == map_end) + if (d == map_end) { err = EFI_OUT_OF_RESOURCES; + } free_pool(map_buf); fail: diff --git a/hypervisor/bsp/uefi/include/bsp/bsp_cfg.h b/hypervisor/bsp/uefi/include/bsp/bsp_cfg.h index d9e926e42..9624a627c 100644 --- a/hypervisor/bsp/uefi/include/bsp/bsp_cfg.h +++ b/hypervisor/bsp/uefi/include/bsp/bsp_cfg.h @@ -18,7 +18,12 @@ #define CONSOLE_LOGLEVEL_DEFAULT 3 #define MEM_LOGLEVEL_DEFAULT 5 #define CONFIG_LOW_RAM_SIZE 0x00010000 -#define CONFIG_RAM_START 0x20000000 + +/* + * By default build the hypervisor in low address + * so that it can only relocate to higher address + */ +#define CONFIG_RAM_START 0x00100000 #define CONFIG_RAM_SIZE 0x02000000 /* 32M */ #define CONFIG_DMAR_PARSE_ENABLED 1 #define CONFIG_GPU_SBDF 0x00000010 /* 0000:00:02.0 */