From cf1515d63c9f351a447819cc583e818a8aea502d Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Thu, 21 Feb 2019 08:53:25 -0800 Subject: [PATCH] hv: optimize the assignment of load addresses for multiboot images bootargs_load_addr (GPA) and zero page which locates at one page follows it: - SOS: currently it's fixed at 0x24EFC000. Theoretically, this address may not exist if the system has small memory size. - pre-launched VMs: currently it's at (vm_config->memory.size - 8KB). It doesn't work if the guest has been assigned for more than 4GB memory size, because zero page must be under 4GB. - This patch reserves 8KB for bootargs_load_addr right before kernel_load_addr for either SOS or pre-launched VMs. ramdisk_load_addr (GPA): - pre-launched VMs: currently it doesn't allow ramdisk. - SOS: currently it's assigned at mods[].mm_mod_start. It's a bug because it misses the hpa2gpa() conversion. - This patch puts ramdisk_load_addr right after (kernel_load_addr + kernel_size), which has 2 benefits: - for pre-launched VMs, mods[].mm_mod_start may be out of its GPA range. - it may be better to consolidate everything (bootarg, kernel, ramdisk) in consecutive GPA, other than spread them out in different places. Tracked-On: #2587 Signed-off-by: Zide Chen Reviewed-by: Eddie Dong Reviewed-by: Victor Sun Acked-by: Anthony Xu --- hypervisor/boot/sbl/multiboot.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/hypervisor/boot/sbl/multiboot.c b/hypervisor/boot/sbl/multiboot.c index 31f1d58dd..482d62944 100644 --- a/hypervisor/boot/sbl/multiboot.c +++ b/hypervisor/boot/sbl/multiboot.c @@ -6,13 +6,10 @@ #include #include -#include #include #include #include -#define BOOT_ARGS_LOAD_ADDR 0x24EFC000 - #define ACRN_DBG_BOOT 6U #define MAX_BOOT_PARAMS_LEN 64U @@ -49,10 +46,11 @@ int32_t init_vm_boot_info(struct acrn_vm *vm) vm->sw.kernel_type = VM_LINUX_GUEST; vm->sw.kernel_info.kernel_src_addr = hpa2hva((uint64_t)mods[0].mm_mod_start); vm->sw.kernel_info.kernel_size = mods[0].mm_mod_end - mods[0].mm_mod_start; - vm->sw.kernel_info.kernel_load_addr = (void *)(16 * 1024 * 1024UL); + vm->sw.kernel_info.kernel_load_addr = (void *)(MEM_1M * 16U); vm->sw.linux_info.bootargs_src_addr = (void *)vm_config->os_config.bootargs; vm->sw.linux_info.bootargs_size = strnlen_s(vm_config->os_config.bootargs, MEM_2K); - vm->sw.linux_info.bootargs_load_addr = (void *)(vm_config->memory.size - 8*1024UL); + vm->sw.linux_info.bootargs_load_addr = + vm->sw.kernel_info.kernel_load_addr - (MEM_1K * 8U); clac(); ret = 0; } @@ -110,7 +108,7 @@ static void parse_other_modules(struct acrn_vm *vm, const struct multiboot_modul if (copy_once != 0) { copy_once = 0; (void)strncpy_s(load_addr, MEM_2K, (const char *)vm->sw.linux_info.bootargs_src_addr, - vm->sw.linux_info.bootargs_size); + vm->sw.linux_info.bootargs_size); vm->sw.linux_info.bootargs_src_addr = load_addr; } @@ -119,7 +117,10 @@ static void parse_other_modules(struct acrn_vm *vm, const struct multiboot_modul } else if (strncmp("RAMDISK", start, type_len) == 0) { vm->sw.linux_info.ramdisk_src_addr = mod_addr; - vm->sw.linux_info.ramdisk_load_addr = (void *)(uint64_t)mods[i].mm_mod_start; + vm->sw.linux_info.ramdisk_load_addr = vm->sw.kernel_info.kernel_load_addr + + vm->sw.kernel_info.kernel_size; + vm->sw.linux_info.ramdisk_load_addr = + (void *)round_page_up((uint64_t)vm->sw.linux_info.ramdisk_load_addr); vm->sw.linux_info.ramdisk_size = mod_size; } else { pr_warn("not support mod, cmd: %s", start); @@ -240,10 +241,12 @@ int32_t init_vm_boot_info(struct acrn_vm *vm) } else { vm->sw.linux_info.bootargs_src_addr = hpa2hva((uint64_t)mods[0].mm_string); vm->sw.linux_info.bootargs_size = - strnlen_s(hpa2hva((uint64_t)mods[0].mm_string), MEM_2K); + strnlen_s(hpa2hva((uint64_t)mods[0].mm_string), MEM_2K); } - vm->sw.linux_info.bootargs_load_addr = (void *)BOOT_ARGS_LOAD_ADDR; + /* Kernel bootarg and zero page are right before the kernel image */ + vm->sw.linux_info.bootargs_load_addr = + vm->sw.kernel_info.kernel_load_addr - (MEM_1K * 8U); if (mbi->mi_mods_count > 1U) { /*parse other modules, like firmware /ramdisk */