diff --git a/hypervisor/arch/x86/guest/ve820.c b/hypervisor/arch/x86/guest/ve820.c index ec669e949..6d27f5ab0 100644 --- a/hypervisor/arch/x86/guest/ve820.c +++ b/hypervisor/arch/x86/guest/ve820.c @@ -177,6 +177,22 @@ static inline uint64_t add_ram_entry(struct e820_entry *entry, uint64_t gpa, uin return round_pde_up(entry->baseaddr + entry->length); } +static uint64_t ve820_find_max_avail_gpa(struct acrn_vm *vm, uint32_t entry_idx) +{ + uint32_t i; + uint64_t max_end_gpa = 0UL; + + for (i = 0U; i < entry_idx; i++) { + const struct e820_entry *entry = &(vm->e820_entries[i]); + + if ((entry->baseaddr + entry->length) > max_end_gpa) { + max_end_gpa = entry->baseaddr + entry->length; + } + } + + return max_end_gpa; +} + /** * @pre vm != NULL * @@ -251,7 +267,8 @@ void create_prelaunched_vm_e820(struct acrn_vm *vm) hpa2_lo_size = remaining_hpa2_size; remaining_hpa2_size = 0; } - (void)add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa2_lo_size); + + gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa2_lo_size); entry_idx++; } @@ -261,5 +278,11 @@ void create_prelaunched_vm_e820(struct acrn_vm *vm) entry_idx++; } + if (vm_config->memory.size_hpa3 > 0UL) { + gpa_start = ve820_find_max_avail_gpa(vm, entry_idx); + gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, vm_config->memory.size_hpa3); + entry_idx++; + } + vm->e820_entry_num = entry_idx; } diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 6b2a027fe..690e07e3b 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -221,6 +221,7 @@ static inline uint16_t get_configured_bsp_pcpu_id(const struct acrn_vm_config *v static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_vm_config *vm_config) { bool is_hpa1 = true; + bool is_hpa2 = true; uint64_t base_hpa = vm_config->memory.start_hpa; uint64_t remaining_hpa_size = vm_config->memory.size; uint32_t i; @@ -245,6 +246,7 @@ static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_ /* Do EPT mapping for GPAs that are backed by physical memory */ if ((entry->type == E820_TYPE_RAM) || (entry->type == E820_TYPE_ACPI_RECLAIM) || (entry->type == E820_TYPE_ACPI_NVS)) { + ept_add_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp, base_hpa, entry->baseaddr, entry->length, EPT_RWX | EPT_WB); base_hpa += entry->length; @@ -262,10 +264,16 @@ static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_ pr_warn("%s: HPA size incorrectly configured in v820\n", __func__); } - if ((remaining_hpa_size == 0UL) && (is_hpa1)) { - is_hpa1 = false; - base_hpa = vm_config->memory.start_hpa2; - remaining_hpa_size = vm_config->memory.size_hpa2; + if (remaining_hpa_size == 0UL) { + if (is_hpa1) { + is_hpa1 = false; + base_hpa = vm_config->memory.start_hpa2; + remaining_hpa_size = vm_config->memory.size_hpa2; + } else if (is_hpa2) { + is_hpa2 = false; + base_hpa = vm_config->memory.start_hpa3; + remaining_hpa_size = vm_config->memory.size_hpa3; + } } } diff --git a/hypervisor/include/arch/x86/vm_config.h b/hypervisor/include/arch/x86/vm_config.h index c5ddf0d68..5b3713c31 100644 --- a/hypervisor/include/arch/x86/vm_config.h +++ b/hypervisor/include/arch/x86/vm_config.h @@ -94,6 +94,10 @@ struct acrn_vm_mem_config { uint64_t start_hpa2; /* Start of second HPA for non-contiguous allocations in VM memory configuration, for pre-launched VMs only */ uint64_t size_hpa2; /* Size of second HPA for non-contiguous allocations in VM memory configuration */ + + uint64_t start_hpa3; /* Start of third HPA for non-contiguous allocations in VM memory configuration, + for pre-launched VMs only */ + uint64_t size_hpa3; /* Size of third HPA for non-contiguous allocations in VM memory configuration */ }; struct target_vuart {