HV: decouple prelaunch VM ve820 from board configs

hypervisor/arch/x86/configs/$(BOARD)/ve820.c is used to store pre-launched
VM specific e820 entries according to memory configuration of customer.
It should be a scenario based configurations but we had to put it in per
board foler because of different board memory settings. This brings concerns
to customer on configuration orgnization.

Currently the file provides same e820 layout for all pre-launched VMs, but
they should have different e820 when their memory are configured differently.
Although we have acrn-config tool to generate ve802.c automatically, it
is not friendly to modify hardcoded ve820 layout manually, so the patch
changes the entries initialization method by calculating each entry item
in C code.

Tracked-On: #4458

Signed-off-by: Victor Sun <victor.sun@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Victor Sun 2020-02-27 15:48:42 +08:00 committed by wenlingz
parent 4c0965d89e
commit d7eac3fe6a
3 changed files with 107 additions and 2 deletions

View File

@ -270,6 +270,7 @@ VP_BASE_C_SRCS += arch/x86/guest/virq.c
VP_BASE_C_SRCS += arch/x86/guest/virtual_cr.c
VP_BASE_C_SRCS += arch/x86/guest/vmexit.c
VP_BASE_C_SRCS += arch/x86/guest/ept.c
VP_BASE_C_SRCS += arch/x86/guest/ve820.c
VP_BASE_C_SRCS += arch/x86/guest/ucode.c
ifeq ($(CONFIG_HYPERV_ENABLED),y)
VP_BASE_C_SRCS += arch/x86/guest/hyperv.c
@ -279,7 +280,6 @@ VP_BASE_C_SRCS += common/hv_main.c
VP_BASE_C_SRCS += common/vm_load.c
VP_BASE_C_SRCS += arch/x86/configs/pci_dev.c
VP_BASE_C_SRCS += arch/x86/configs/vacpi.c
VP_BASE_C_SRCS += arch/x86/configs/$(CONFIG_BOARD)/ve820.c
# virtual platform device model
VP_DM_C_SRCS += dm/vpic.c

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <e820.h>
#include <mmu.h>
#include <vm.h>
#define ENTRY_HPA1 2U
#define ENTRY_HPA1_HI 4U
static struct e820_entry pre_vm_e820[PRE_VM_NUM][E820_MAX_ENTRIES];
static const struct e820_entry pre_ve820_template[E820_MAX_ENTRIES] = {
{ /* usable RAM under 1MB */
.baseaddr = 0x0UL,
.length = 0xF0000UL, /* 960KB */
.type = E820_TYPE_RAM
},
{ /* mptable */
.baseaddr = 0xF0000UL, /* 960KB */
.length = 0x10000UL, /* 64KB */
.type = E820_TYPE_RESERVED
},
{ /* hpa1 */
.baseaddr = 0x100000UL, /* 1MB */
.length = (MEM_2G - MEM_1M),
.type = E820_TYPE_RAM
},
{ /* 32bit PCI hole */
.baseaddr = 0x80000000UL, /* 2048MB */
.length = MEM_2G,
.type = E820_TYPE_RESERVED
},
};
/**
* @pre entry != NULL
*/
static inline uint64_t add_ram_entry(struct e820_entry *entry, uint64_t gpa, uint64_t length)
{
entry->baseaddr = gpa;
entry->length = length;
entry->type = E820_TYPE_RAM;
return round_pde_up(entry->baseaddr + entry->length);
}
/**
* @pre vm != NULL
*
* ve820 layout for pre-launched VM:
*
* entry0: usable under 1MB
* entry1: reserved for MP Table from 0xf0000 to 0xfffff
* entry2: usable for hpa1 or hpa1_lo from 0x100000
* entry3: reserved for 32bit PCI hole from 0x80000000 to 0xffffffff
* (entry4): usable for
* a) hpa1_hi, if hpa1 > 2GB
* b) hpa2, if (hpa1 + hpa2) < 2GB
* c) hpa2_lo, if hpa1 < 2GB and (hpa1 + hpa2) > 2GB
* (entry5): usable for
* a) hpa2, if hpa1 > 2GB
* b) hpa2_hi, if hpa1 < 2GB and (hpa1 + hpa2) > 2GB
*/
void create_prelaunched_vm_e820(struct acrn_vm *vm)
{
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
uint64_t gpa_start = 0x100000000UL;
uint64_t hpa1_hi_size, hpa2_lo_size;
uint64_t remaining_hpa2_size = vm_config->memory.size_hpa2;
uint32_t entry_idx = ENTRY_HPA1_HI;
vm->e820_entries = pre_vm_e820[vm->vm_id];
(void)memcpy_s((void *)vm->e820_entries, E820_MAX_ENTRIES * sizeof(struct e820_entry),
(const void *)pre_ve820_template, E820_MAX_ENTRIES * sizeof(struct e820_entry));
/* sanitize entry for hpa1 */
if (vm_config->memory.size > MEM_2G) {
/* need to split hpa1 and add an entry for hpa1_hi */
hpa1_hi_size = vm_config->memory.size - MEM_2G;
gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa1_hi_size);
entry_idx++;
} else {
/* need to revise length of hpa1 entry to its actual size */
vm->e820_entries[ENTRY_HPA1].length = vm_config->memory.size - MEM_1M;
if ((vm_config->memory.size < MEM_2G)
&& (remaining_hpa2_size > (MEM_2G - vm_config->memory.size))) {
/* need to split hpa2 and add an entry for hpa2_lo */
hpa2_lo_size = remaining_hpa2_size - (MEM_2G - vm_config->memory.size);
gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, hpa2_lo_size);
remaining_hpa2_size -= hpa2_lo_size;
entry_idx++;
}
}
/* check whether need an entry for remaining hpa2 */
if (remaining_hpa2_size > 0UL) {
gpa_start = add_ram_entry((vm->e820_entries + entry_idx), gpa_start, remaining_hpa2_size);
entry_idx++;
}
vm->e820_entry_num = entry_idx;
}

View File

@ -123,7 +123,7 @@ struct acrn_vm {
struct vm_sw_info sw; /* Reference to SW associated with this VM */
struct vm_pm_info pm; /* Reference to this VM's arch information */
uint32_t e820_entry_num;
const struct e820_entry *e820_entries;
struct e820_entry *e820_entries;
uint16_t vm_id; /* Virtual machine identifier */
enum vm_state state; /* VM state */
struct acrn_vuart vuart[MAX_VUART_NUM_PER_VM]; /* Virtual UART */