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 <gen.zheng@intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Reviewed-by: Yin fengwei <fengwei.yin@intel.com>
This commit is contained in:
Zide Chen 2018-06-22 09:02:49 -07:00 committed by lijinxia
parent 84d9da1d6a
commit 6c9e451b41
4 changed files with 37 additions and 39 deletions

View File

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

View File

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

View File

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

View File

@ -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 */