From 60857819839dcb7d269cd6ed28adca29e9db5887 Mon Sep 17 00:00:00 2001 From: Chaohong guo Date: Mon, 17 Sep 2018 13:32:11 +0800 Subject: [PATCH] Replace __emalloc() with a call to uefi allocate_page() UEFI provides the func allocate_pages() with the option of AllocateAddress and AllocateMaxAddress to allocate memory at fixed address or below the specified address respectively. Make use of the interface, simplify the memory allocation for hyperivosr when CONFIG_RELOC is enabled. Tracked-On:#1260 Signed-off-by: Chaohong Guo Reviewedd-by: Anthony Xu Acked-by: Gen Zheng --- hypervisor/bsp/uefi/efi/boot.c | 14 ++++++- hypervisor/bsp/uefi/efi/efilinux.h | 17 ++++++++ hypervisor/bsp/uefi/efi/malloc.c | 66 ------------------------------ 3 files changed, 29 insertions(+), 68 deletions(-) diff --git a/hypervisor/bsp/uefi/efi/boot.c b/hypervisor/bsp/uefi/efi/boot.c index d2282f523..12195e728 100644 --- a/hypervisor/bsp/uefi/efi/boot.c +++ b/hypervisor/bsp/uefi/efi/boot.c @@ -369,8 +369,18 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table) goto failed; } - err = __emalloc(CONFIG_RAM_SIZE, CONFIG_RAM_START, &hv_hpa, - EfiReservedMemoryType); + /* without relocateion enabled, hypervisor binary need to reside in + * fixed memory address starting from CONFIG_RAM_START, make a call + * to emalloc_fixed_addr for that case. With CONFIG_RELOC enabled, + * hypervisor is able to do relocation, the only requirement is that + * it need to reside in memory below 4GB, call emalloc_reserved_mem() + * instead. + */ +#ifdef CONFIG_RELOC + err = emalloc_reserved_mem(&hv_hpa, CONFIG_RAM_SIZE, MEM_ADDR_4GB); +#else + err = emalloc_fixed_addr(&hv_hpa, CONFIG_RAM_SIZE, CONFIG_RAM_START); +#endif if (err != EFI_SUCCESS) goto failed; diff --git a/hypervisor/bsp/uefi/efi/efilinux.h b/hypervisor/bsp/uefi/efi/efilinux.h index 70aad77e2..9ca542c89 100644 --- a/hypervisor/bsp/uefi/efi/efilinux.h +++ b/hypervisor/bsp/uefi/efi/efilinux.h @@ -46,6 +46,7 @@ #define EFILINUX_VERSION_MINOR 0 #define MEM_ADDR_1MB (1 << 20) +#define MEM_ADDR_4GB (0xFFFFFFFF) extern EFI_SYSTEM_TABLE *sys_table; @@ -202,6 +203,22 @@ static inline EFI_STATUS emalloc_reserved_mem(EFI_PHYSICAL_ADDRESS *addr, EFI_SIZE_TO_PAGES(size), addr); } + +/* + * emalloc_fixed_addr - it is called to allocate memory hypervisor itself + * when CONFIG_RELOC config is NOT enable.And mark the allocated memory as + * EfiReserved memory type so that SOS won't touch it during boot. + * @addr: a pointer to the allocated address on success + * @size: size in bytes of the requested allocation + */ +static inline EFI_STATUS emalloc_fixed_addr(EFI_PHYSICAL_ADDRESS *addr, + UINTN size, EFI_PHYSICAL_ADDRESS fixed_addr) +{ + *addr = fixed_addr; + return allocate_pages(AllocateAddress, EfiReservedMemoryType, + EFI_SIZE_TO_PAGES(size), addr); +} + /** * exit - Terminate a loaded EFI image * @image: firmware-allocated handle that identifies the image diff --git a/hypervisor/bsp/uefi/efi/malloc.c b/hypervisor/bsp/uefi/efi/malloc.c index 087670ca5..efd94ec70 100644 --- a/hypervisor/bsp/uefi/efi/malloc.c +++ b/hypervisor/bsp/uefi/efi/malloc.c @@ -164,72 +164,6 @@ fail: return err; } -EFI_STATUS __emalloc(UINTN size, UINTN min_addr, EFI_PHYSICAL_ADDRESS *addr, - EFI_MEMORY_TYPE mem_type) -{ - UINTN map_size, map_key, desc_size; - EFI_MEMORY_DESCRIPTOR *map_buf; - UINTN d, map_end; - UINT32 desc_version; - EFI_STATUS err; - UINTN nr_pages = EFI_SIZE_TO_PAGES(size); - - err = memory_map(&map_buf, &map_size, &map_key, - &desc_size, &desc_version); - if (err != EFI_SUCCESS) - goto fail; - - 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; - start = desc->PhysicalStart; - end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT); - - if ((min_addr > start) && (min_addr < end)) { - start = min_addr; - } - - 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; - } - -#ifdef CONFIG_RELOC - aligned = start; -#else - aligned = min_addr; -#endif - err = allocate_pages(AllocateAddress, mem_type, - nr_pages, &aligned); - if (err == EFI_SUCCESS) { - *addr = aligned; - break; - } - } - - if (d == map_end) { - err = EFI_OUT_OF_RESOURCES; - } - - free_pool(map_buf); -fail: - return err; -} /** * efree - Return memory allocated with emalloc