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 <chaohong.guo@intel.com>
Reviewed-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Chaohong guo 2019-01-16 14:00:17 +08:00 committed by wenlingz
parent ea143dc43b
commit 3fee32c0bb
2 changed files with 29 additions and 31 deletions

View File

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

View File

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