HV: vm_load: remove load_sw_modules() api

In load_sw_modules() implementation, we always assuming the guest kernel
module has one load address and then the whole kernel image would be loaded
to guest space from its load address. This is not true when guest kernel
has multiple load addresses like ELF format kernel image.

This patch removes load_sw_modules() API, and the loading method of each
format of kernel image could be specified in prepare_loading_xxximage() API.

Tracked-On: #6323

Signed-off-by: Victor Sun <victor.sun@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
Victor Sun 2021-06-20 21:09:10 +08:00 committed by wenlingz
parent 2938eca363
commit afe24731a7
1 changed files with 33 additions and 42 deletions

View File

@ -175,6 +175,16 @@ static uint64_t create_zero_page(struct acrn_vm *vm, uint64_t load_params_gpa)
return gpa; return gpa;
} }
/**
* @pre sw_module != NULL
*/
static void load_sw_module(struct acrn_vm *vm, struct sw_module_info *sw_module)
{
if ((sw_module->size != 0) && (sw_module->load_addr != NULL)) {
(void)copy_to_gpa(vm, sw_module->src_addr, (uint64_t)sw_module->load_addr, sw_module->size);
}
}
/** /**
* @pre vm != NULL * @pre vm != NULL
*/ */
@ -184,6 +194,25 @@ static void prepare_loading_bzimage(struct acrn_vm *vm, struct acrn_vcpu *vcpu,
uint32_t kernel_entry_offset; uint32_t kernel_entry_offset;
struct zero_page *zeropage; struct zero_page *zeropage;
struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info); struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info);
struct sw_module_info *bootargs_info = &(vm->sw.bootargs_info);
struct sw_module_info *ramdisk_info = &(vm->sw.ramdisk_info);
struct sw_module_info *acpi_info = &(vm->sw.acpi_info);
/* Copy the guest kernel image to its run-time location */
(void)copy_to_gpa(vm, sw_kernel->kernel_src_addr,
(uint64_t)sw_kernel->kernel_load_addr, sw_kernel->kernel_size);
/* Don't need to load ramdisk if src_addr and load_addr are pointed to same place. */
if (gpa2hva(vm, (uint64_t)ramdisk_info->load_addr) != ramdisk_info->src_addr) {
load_sw_module(vm, ramdisk_info);
}
bootargs_info->load_addr = (void *)BZIMG_CMDLINE_GPA(load_params_gpa);
load_sw_module(vm, bootargs_info);
/* Copy Guest OS ACPI to its load location */
load_sw_module(vm, acpi_info);
/* calculate the kernel entry point */ /* calculate the kernel entry point */
zeropage = (struct zero_page *)sw_kernel->kernel_src_addr; zeropage = (struct zero_page *)sw_kernel->kernel_src_addr;
@ -218,51 +247,17 @@ static void prepare_loading_bzimage(struct acrn_vm *vm, struct acrn_vcpu *vcpu,
static void prepare_loading_rawimage(struct acrn_vm *vm) static void prepare_loading_rawimage(struct acrn_vm *vm)
{ {
struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info); struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info);
const struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
sw_kernel->kernel_entry_addr = (void *)vm_config->os_config.kernel_entry_addr;
}
/**
* @pre sw_module != NULL
*/
static void load_sw_module(struct acrn_vm *vm, struct sw_module_info *sw_module)
{
if (sw_module->size != 0) {
(void)copy_to_gpa(vm, sw_module->src_addr, (uint64_t)sw_module->load_addr, sw_module->size);
}
}
/**
* @pre vm != NULL
*/
static void load_sw_modules(struct acrn_vm *vm, uint64_t load_params_gpa)
{
struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info);
struct sw_module_info *bootargs_info = &(vm->sw.bootargs_info);
struct sw_module_info *ramdisk_info = &(vm->sw.ramdisk_info);
struct sw_module_info *acpi_info = &(vm->sw.acpi_info); struct sw_module_info *acpi_info = &(vm->sw.acpi_info);
const struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
pr_dbg("Loading guest to run-time location");
/* Copy the guest kernel image to its run-time location */ /* Copy the guest kernel image to its run-time location */
(void)copy_to_gpa(vm, sw_kernel->kernel_src_addr, (void)copy_to_gpa(vm, sw_kernel->kernel_src_addr,
(uint64_t)sw_kernel->kernel_load_addr, sw_kernel->kernel_size); (uint64_t)sw_kernel->kernel_load_addr, sw_kernel->kernel_size);
if (vm->sw.kernel_type == KERNEL_BZIMAGE) {
/* Don't need to load ramdisk if src_addr and load_addr are pointed to same place. */
if (gpa2hva(vm, (uint64_t)ramdisk_info->load_addr) != ramdisk_info->src_addr) {
load_sw_module(vm, ramdisk_info);
}
bootargs_info->load_addr = (void *)BZIMG_CMDLINE_GPA(load_params_gpa);
load_sw_module(vm, bootargs_info);
}
/* Copy Guest OS ACPI to its load location */ /* Copy Guest OS ACPI to its load location */
load_sw_module(vm, acpi_info); load_sw_module(vm, acpi_info);
sw_kernel->kernel_entry_addr = (void *)vm_config->os_config.kernel_entry_addr;
} }
static int32_t vm_bzimage_loader(struct acrn_vm *vm) static int32_t vm_bzimage_loader(struct acrn_vm *vm)
@ -276,8 +271,6 @@ static int32_t vm_bzimage_loader(struct acrn_vm *vm)
/* We boot bzImage from protected mode directly */ /* We boot bzImage from protected mode directly */
init_vcpu_protect_mode_regs(vcpu, BZIMG_INITGDT_GPA(load_params_gpa)); init_vcpu_protect_mode_regs(vcpu, BZIMG_INITGDT_GPA(load_params_gpa));
load_sw_modules(vm, load_params_gpa);
prepare_loading_bzimage(vm, vcpu, load_params_gpa); prepare_loading_bzimage(vm, vcpu, load_params_gpa);
} else { } else {
ret = -ENOMEM; ret = -ENOMEM;
@ -289,7 +282,7 @@ static int32_t vm_bzimage_loader(struct acrn_vm *vm)
static int32_t vm_rawimage_loader(struct acrn_vm *vm) static int32_t vm_rawimage_loader(struct acrn_vm *vm)
{ {
int32_t ret = 0; int32_t ret = 0;
uint64_t load_params_gpa = 0x800; uint64_t vgdt_gpa = 0x800;
/* /*
* TODO: * TODO:
@ -299,9 +292,7 @@ static int32_t vm_rawimage_loader(struct acrn_vm *vm)
* currently we only support Zephyr which has no needs on cmdline/e820/efimmap/etc. * currently we only support Zephyr which has no needs on cmdline/e820/efimmap/etc.
* hardcode the vGDT GPA to 0x800 where is not used by Zephyr so far; * hardcode the vGDT GPA to 0x800 where is not used by Zephyr so far;
*/ */
init_vcpu_protect_mode_regs(vcpu_from_vid(vm, BSP_CPU_ID), load_params_gpa); init_vcpu_protect_mode_regs(vcpu_from_vid(vm, BSP_CPU_ID), vgdt_gpa);
load_sw_modules(vm, load_params_gpa);
prepare_loading_rawimage(vm); prepare_loading_rawimage(vm);