diff --git a/hypervisor/boot/boot.c b/hypervisor/boot/boot.c index 7dc1fdca3..e06e8ef9e 100644 --- a/hypervisor/boot/boot.c +++ b/hypervisor/boot/boot.c @@ -23,7 +23,7 @@ int32_t sanitize_acrn_boot_info(struct acrn_boot_info *abi) { int32_t abi_status = 0; - if (abi->mi_mods_count == 0U) { + if (abi->mods_count == 0U) { pr_err("no boot module info found"); abi_status = -EINVAL; } diff --git a/hypervisor/boot/guest/vboot_info.c b/hypervisor/boot/guest/vboot_info.c index 0063cda52..e1459c336 100644 --- a/hypervisor/boot/guest/vboot_info.c +++ b/hypervisor/boot/guest/vboot_info.c @@ -24,24 +24,22 @@ /** * @pre vm != NULL && mod != NULL */ -static void init_vm_ramdisk_info(struct acrn_vm *vm, const struct multiboot_module *mod) +static void init_vm_ramdisk_info(struct acrn_vm *vm, const struct abi_module *mod) { - void *mod_addr = hpa2hva((uint64_t)mod->mm_mod_start); - - if ((mod_addr != NULL) && (mod->mm_mod_end > mod->mm_mod_start)) { - vm->sw.ramdisk_info.src_addr = mod_addr; + if (mod->start != NULL) { + vm->sw.ramdisk_info.src_addr = mod->start; vm->sw.ramdisk_info.load_addr = vm->sw.kernel_info.kernel_load_addr + vm->sw.kernel_info.kernel_size; vm->sw.ramdisk_info.load_addr = (void *)round_page_up((uint64_t)vm->sw.ramdisk_info.load_addr); - vm->sw.ramdisk_info.size = mod->mm_mod_end - mod->mm_mod_start; + vm->sw.ramdisk_info.size = mod->size; } } /** * @pre vm != NULL && mod != NULL */ -static void init_vm_acpi_info(struct acrn_vm *vm, const struct multiboot_module *mod) +static void init_vm_acpi_info(struct acrn_vm *vm, const struct abi_module *mod) { - vm->sw.acpi_info.src_addr = hpa2hva((uint64_t)mod->mm_mod_start); + vm->sw.acpi_info.src_addr = mod->start; vm->sw.acpi_info.load_addr = (void *)VIRT_ACPI_DATA_ADDR; vm->sw.acpi_info.size = ACPI_MODULE_SIZE; } @@ -88,24 +86,24 @@ static void *get_kernel_load_addr(struct acrn_vm *vm) /** * @pre vm != NULL && mod != NULL */ -static int32_t init_vm_kernel_info(struct acrn_vm *vm, const struct multiboot_module *mod) +static int32_t init_vm_kernel_info(struct acrn_vm *vm, const struct abi_module *mod) { struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); - dev_dbg(DBG_LEVEL_BOOT, "kernel mod start=0x%x, end=0x%x", - mod->mm_mod_start, mod->mm_mod_end); + dev_dbg(DBG_LEVEL_BOOT, "kernel mod start=0x%x, size=0x%x", + (uint64_t)mod->start, mod->size); vm->sw.kernel_type = vm_config->os_config.kernel_type; - vm->sw.kernel_info.kernel_src_addr = hpa2hva((uint64_t)mod->mm_mod_start); - if ((vm->sw.kernel_info.kernel_src_addr != NULL) && (mod->mm_mod_end > mod->mm_mod_start)){ - vm->sw.kernel_info.kernel_size = mod->mm_mod_end - mod->mm_mod_start; + vm->sw.kernel_info.kernel_src_addr = mod->start; + if (vm->sw.kernel_info.kernel_src_addr != NULL) { + vm->sw.kernel_info.kernel_size = mod->size; vm->sw.kernel_info.kernel_load_addr = get_kernel_load_addr(vm); } return (vm->sw.kernel_info.kernel_load_addr == NULL) ? (-EINVAL) : 0; } -/* cmdline parsed from multiboot module string, for pre-launched VMs and SOS VM only. */ +/* cmdline parsed from abi module string, for pre-launched VMs and SOS VM only. */ static char mod_cmdline[PRE_VM_NUM + SOS_VM_NUM][MAX_BOOTARGS_SIZE] = { '\0' }; /** @@ -116,7 +114,7 @@ static void init_vm_bootargs_info(struct acrn_vm *vm, const struct acrn_boot_inf struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); vm->sw.bootargs_info.src_addr = vm_config->os_config.bootargs; - /* If multiboot string of the kernel module exists, it would OVERRIDE the pre-configured build-in VM bootargs, + /* If module string of the kernel module exists, it would OVERRIDE the pre-configured build-in VM bootargs, * which means we give user a chance to re-configure VM bootargs at bootloader runtime. e.g. GRUB menu */ if (mod_cmdline[vm->vm_id][0] != '\0') { @@ -164,22 +162,22 @@ static void init_vm_bootargs_info(struct acrn_vm *vm, const struct acrn_boot_inf /* @pre abi != NULL && tag != NULL */ -static struct multiboot_module *get_mod_by_tag(const struct acrn_boot_info *abi, const char *tag) +static struct abi_module *get_mod_by_tag(const struct acrn_boot_info *abi, const char *tag) { uint8_t i; - struct multiboot_module *mod = NULL; - struct multiboot_module *mods = (struct multiboot_module *)(&abi->mi_mods[0]); + struct abi_module *mod = NULL; + struct abi_module *mods = (struct abi_module *)(&abi->mods[0]); uint32_t tag_len = strnlen_s(tag, MAX_MOD_TAG_LEN); - for (i = 0U; i < abi->mi_mods_count; i++) { - const char *mm_string = (char *)hpa2hva((uint64_t)(mods + i)->mm_string); - uint32_t mm_str_len = strnlen_s(mm_string, MAX_MOD_TAG_LEN); - const char *p_chr = mm_string + tag_len; /* point to right after the end of tag */ + for (i = 0U; i < abi->mods_count; i++) { + const char *string = (char *)hpa2hva((uint64_t)(mods + i)->string); + uint32_t str_len = strnlen_s(string, MAX_MOD_TAG_LEN); + const char *p_chr = string + tag_len; /* point to right after the end of tag */ - /* The tag must be located at the first word in mm_string and end with SPACE/TAB or EOL since - * when do file stitch by tool, the tag in mm_string might be followed by EOL(0x0d/0x0a). + /* The tag must be located at the first word in string and end with SPACE/TAB or EOL since + * when do file stitch by tool, the tag in string might be followed by EOL(0x0d/0x0a). */ - if ((mm_str_len >= tag_len) && (strncmp(mm_string, tag, tag_len) == 0) + if ((str_len >= tag_len) && (strncmp(string, tag, tag_len) == 0) && (is_space(*p_chr) || is_eol(*p_chr))) { mod = mods + i; break; @@ -188,8 +186,8 @@ static struct multiboot_module *get_mod_by_tag(const struct acrn_boot_info *abi, /* GRUB might put module at address 0 or under 1MB in the case that the module size is less then 1MB * ACRN will not support these cases */ - if ((mod != NULL) && ((mod->mm_mod_start == 0U) || (mod->mm_mod_end <= MEM_1M))) { - pr_err("Unsupported multiboot module: start at 0x%x, end at 0x%x", mod->mm_mod_start, mod->mm_mod_end); + if ((mod != NULL) && (mod->start == NULL)) { + pr_err("Unsupported module: start at HPA 0, size 0x%x .", mod->size); mod = NULL; } @@ -201,21 +199,21 @@ static struct multiboot_module *get_mod_by_tag(const struct acrn_boot_info *abi, static int32_t init_vm_sw_load(struct acrn_vm *vm, const struct acrn_boot_info *abi) { struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); - struct multiboot_module *mod; + struct abi_module *mod; int32_t ret = -EINVAL; - dev_dbg(DBG_LEVEL_BOOT, "mod counts=%d\n", abi->mi_mods_count); + dev_dbg(DBG_LEVEL_BOOT, "mod counts=%d\n", abi->mods_count); /* find kernel module first */ mod = get_mod_by_tag(abi, vm_config->os_config.kernel_mod_tag); if (mod != NULL) { - const char *mm_string = (char *)hpa2hva((uint64_t)mod->mm_string); - uint32_t mm_str_len = strnlen_s(mm_string, MAX_BOOTARGS_SIZE); + const char *string = (char *)hpa2hva((uint64_t)mod->string); + uint32_t str_len = strnlen_s(string, MAX_BOOTARGS_SIZE); uint32_t tag_len = strnlen_s(vm_config->os_config.kernel_mod_tag, MAX_MOD_TAG_LEN); - const char *p_chr = mm_string + tag_len + 1; /* point to the possible start of cmdline */ + const char *p_chr = string + tag_len + 1; /* point to the possible start of cmdline */ /* check whether there is a cmdline configured in module string */ - if (((mm_str_len > (tag_len + 1U))) && (is_space(*(p_chr - 1))) && (!is_eol(*p_chr))) { + if (((str_len > (tag_len + 1U))) && (is_space(*(p_chr - 1))) && (!is_eol(*p_chr))) { (void)strncpy_s(&mod_cmdline[vm->vm_id][0], MAX_BOOTARGS_SIZE, p_chr, (MAX_BOOTARGS_SIZE - 1U)); } @@ -236,7 +234,7 @@ static int32_t init_vm_sw_load(struct acrn_vm *vm, const struct acrn_boot_info * if (is_prelaunched_vm(vm)) { mod = get_mod_by_tag(abi, vm_config->acpi_config.acpi_mod_tag); - if ((mod != NULL) && ((mod->mm_mod_end - mod->mm_mod_start) == ACPI_MODULE_SIZE)) { + if ((mod != NULL) && (mod->size == ACPI_MODULE_SIZE)) { init_vm_acpi_info(vm, mod); } else { pr_err("failed to load VM %d acpi module", vm->vm_id); diff --git a/hypervisor/boot/include/boot.h b/hypervisor/boot/include/boot.h index d481de9fc..175e69f49 100644 --- a/hypervisor/boot/include/boot.h +++ b/hypervisor/boot/include/boot.h @@ -17,6 +17,7 @@ #define MAX_BOOTARGS_SIZE 2048U #define MAX_LOADER_NAME_SIZE 32U #define MAX_PROTOCOL_NAME_SIZE 16U +#define MAX_MOD_STRING_SIZE 2048U /* The modules in multiboot are: Pre-launched VM: kernel/ramdisk/acpi; SOS VM: kernel/ramdisk */ #define MAX_MODULE_NUM (3U * PRE_VM_NUM + 2U * SOS_VM_NUM) @@ -24,14 +25,20 @@ /* The vACPI module size is fixed to 1MB */ #define ACPI_MODULE_SIZE MEM_1M +struct abi_module { + void *start; /* HVA */ + uint32_t size; + const char string[MAX_MOD_STRING_SIZE]; +}; + struct acrn_boot_info { char protocol_name[MAX_PROTOCOL_NAME_SIZE]; const char cmdline[MAX_BOOTARGS_SIZE]; const char loader_name[MAX_LOADER_NAME_SIZE]; - uint32_t mi_mods_count; - struct multiboot_module mi_mods[MAX_MODULE_NUM]; + uint32_t mods_count; + struct abi_module mods[MAX_MODULE_NUM]; uint32_t mi_mmap_entries; struct multiboot_mmap mi_mmap_entry[MAX_MMAP_ENTRIES]; diff --git a/hypervisor/boot/multiboot/multiboot.c b/hypervisor/boot/multiboot/multiboot.c index 181673c28..35eaacb66 100644 --- a/hypervisor/boot/multiboot/multiboot.c +++ b/hypervisor/boot/multiboot/multiboot.c @@ -14,6 +14,7 @@ * @pre abi != NULL */ int32_t multiboot_to_acrn_bi(struct acrn_boot_info *abi, void *mb_info) { + uint32_t i; struct multiboot_info *mbi = (struct multiboot_info *)(hpa2hva_early((uint64_t)mb_info)); struct multiboot_mmap *mmap = (struct multiboot_mmap *)hpa2hva_early((uint64_t)mbi->mi_mmap_addr); struct multiboot_module *mods = (struct multiboot_module *)hpa2hva_early((uint64_t)mbi->mi_mods_addr); @@ -26,7 +27,6 @@ int32_t multiboot_to_acrn_bi(struct acrn_boot_info *abi, void *mb_info) { strnlen_s((char *)hpa2hva_early((uint64_t)mbi->mi_loader_name), (MAX_LOADER_NAME_SIZE - 1U))); abi->mi_mmap_entries = mbi->mi_mmap_length / sizeof(struct multiboot_mmap); - abi->mi_mods_count = mbi->mi_mods_count; if (((mbi->mi_flags & MULTIBOOT_INFO_HAS_MMAP) != 0U) && (abi->mi_mmap_entries != 0U) && (mmap != NULL)) { @@ -42,16 +42,23 @@ int32_t multiboot_to_acrn_bi(struct acrn_boot_info *abi, void *mb_info) { abi->mi_mmap_entries = 0U; } - if (((mbi->mi_flags & MULTIBOOT_INFO_HAS_MODS) != 0U) && (abi->mi_mods_count != 0U) && (mods != NULL)) { - if (abi->mi_mods_count > MAX_MODULE_NUM) { - abi->mi_mods_count = MAX_MODULE_NUM; + abi->mods_count = mbi->mi_mods_count; + if (((mbi->mi_flags & MULTIBOOT_INFO_HAS_MODS) != 0U) && (mbi->mi_mods_count != 0U) && (mods != NULL)) { + if (abi->mods_count > MAX_MODULE_NUM) { + abi->mods_count = MAX_MODULE_NUM; } - (void)memcpy_s((void *)(&abi->mi_mods[0]), - (abi->mi_mods_count * sizeof(struct multiboot_module)), - mods, (abi->mi_mods_count * sizeof(struct multiboot_module))); + for (i = 0U; i < abi->mods_count; i++) { + abi->mods[i].start = hpa2hva_early((uint64_t)(mods + i)->mm_mod_start); + if ((mods + i)->mm_mod_end > (mods + i)->mm_mod_start) { + abi->mods[i].size = (mods + i)->mm_mod_end - (mods + i)->mm_mod_start; + } + (void)strncpy_s((void *)(abi->mods[i].string), MAX_MOD_STRING_SIZE, + (char *)hpa2hva_early((uint64_t)(mods + i)->mm_string), + strnlen_s((char *)hpa2hva_early((uint64_t)(mods + i)->mm_string), MAX_BOOTARGS_SIZE)); + } } else { - abi->mi_mods_count = 0U; + abi->mods_count = 0U; } return 0; diff --git a/hypervisor/boot/multiboot/multiboot2.c b/hypervisor/boot/multiboot/multiboot2.c index 9b6520153..a4af6a176 100644 --- a/hypervisor/boot/multiboot/multiboot2.c +++ b/hypervisor/boot/multiboot/multiboot2.c @@ -37,11 +37,14 @@ static void mb2_mmap_to_abi(struct acrn_boot_info *abi, const struct multiboot2_ static void mb2_mods_to_abi(struct acrn_boot_info *abi, uint32_t mbi_mod_idx, const struct multiboot2_tag_module *mb2_tag_mods) { - if (mbi_mod_idx < MAX_MODULE_NUM) { - abi->mi_mods[mbi_mod_idx].mm_mod_start = mb2_tag_mods->mod_start; - abi->mi_mods[mbi_mod_idx].mm_mod_end = mb2_tag_mods->mod_end; - abi->mi_mods[mbi_mod_idx].mm_string = (uint32_t)(uint64_t)mb2_tag_mods->cmdline; + abi->mods[mbi_mod_idx].start = hpa2hva_early((uint64_t)mb2_tag_mods->mod_start); + if (mb2_tag_mods->mod_end > mb2_tag_mods->mod_start) { + abi->mods[mbi_mod_idx].size = mb2_tag_mods->mod_end - mb2_tag_mods->mod_start; } + + (void)strncpy_s((void *)(abi->mods[mbi_mod_idx].string), MAX_MOD_STRING_SIZE, + (char *)hpa2hva_early((uint64_t)mb2_tag_mods->cmdline), + strnlen_s((char *)hpa2hva_early((uint64_t)mb2_tag_mods->cmdline), MAX_MOD_STRING_SIZE)); } /** @@ -94,8 +97,10 @@ int32_t multiboot2_to_acrn_bi(struct acrn_boot_info *abi, void *mb2_info) mb2_mmap_to_abi(abi, (const struct multiboot2_tag_mmap *)mb2_tag); break; case MULTIBOOT2_TAG_TYPE_MODULE: - mb2_mods_to_abi(abi, mod_idx, (const struct multiboot2_tag_module *)mb2_tag); - mod_idx++; + if (mod_idx < MAX_MODULE_NUM) { + mb2_mods_to_abi(abi, mod_idx, (const struct multiboot2_tag_module *)mb2_tag); + mod_idx++; + } break; case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME: str = ((struct multiboot2_tag_string *)mb2_tag)->string; @@ -132,7 +137,7 @@ int32_t multiboot2_to_acrn_bi(struct acrn_boot_info *abi, void *mb2_info) + ((mb2_tag->size + (MULTIBOOT2_INFO_ALIGN - 1U)) & ~(MULTIBOOT2_INFO_ALIGN - 1U))); } - abi->mi_mods_count = mod_idx; + abi->mods_count = mod_idx; return ret; }