hv: add support to assign 3rd non-contiguous HPA regions for logical partition scenario

Currently acrn supports 2 non-contiguous HPA regions (HPA1 and HPA2), extend
the code to support 3rd non-contiguous HPA region (HPA3) for logical partition scenario
(hybrid scenario is not supported)

To keep things simple, current design has the following assumptions for
ve820 and ept mapping:
 1. HPA2 will always be placed after HPA1
 2. HPA3 will always be placed after HPA2
 3. HPA1/HPA2/HPA3 don’t share a single ve820 entry.
  (Create multiple entries if needed but not shared)

Tracked-On: #6145
Signed-off-by: dongshen <dongsheng.x.zhang@intel.com>
This commit is contained in:
dongshen 2021-06-01 14:46:19 -07:00 committed by wenlingz
parent 16d517a84d
commit 0ac2e21f20
3 changed files with 40 additions and 5 deletions

View File

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

View File

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

View File

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