From 2b35c07857af14cbb11faea963825e887fa4d41e Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Tue, 26 Feb 2019 23:26:55 -0800 Subject: [PATCH] hv: do EPT mapping only for physical memory backed GPA on pre-launched VMs Currently for pre-launched VMs, HV intends to do EPT mapping for all GPA space, which implies that it wastes HPA to back PCI hole and other vE820 entries that are not backed by physical memory. This patch solves this issue and fixes ve820 entries whose length is not aligned to 4K, and changes the lowmem entry's start GPA from 1MB to 2MB. Tracked-On: #2587 Signed-off-by: Zide Chen Acked-by: Anthony Xu --- hypervisor/arch/x86/configs/apl-mrb/ve820.c | 28 ++++++++-------- hypervisor/arch/x86/configs/dnv-cb2/ve820.c | 28 ++++++++-------- hypervisor/arch/x86/guest/vm.c | 37 +++++++++++++++++++-- 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/hypervisor/arch/x86/configs/apl-mrb/ve820.c b/hypervisor/arch/x86/configs/apl-mrb/ve820.c index 90576f1ea..a5c5332da 100644 --- a/hypervisor/arch/x86/configs/apl-mrb/ve820.c +++ b/hypervisor/arch/x86/configs/apl-mrb/ve820.c @@ -7,33 +7,33 @@ #include const struct e820_entry ve820_entry[E820_MAX_ENTRIES] = { - { /* 0 to mptable */ + { /* usable RAM under 1MB */ .baseaddr = 0x0UL, - .length = 0xEFFFFUL, + .length = 0xF0000UL, /* 960KB */ .type = E820_TYPE_RAM }, - { /* mptable 65536U */ - .baseaddr = 0xF0000UL, - .length = 0x10000UL, + { /* mptable */ + .baseaddr = 0xF0000UL, /* 960KB */ + .length = 0x10000UL, /* 16KB */ .type = E820_TYPE_RESERVED }, - { /* mptable to lowmem */ - .baseaddr = 0x100000UL, - .length = 0x1FF00000UL, + { /* lowmem */ + .baseaddr = 0x200000UL, /* 2MB */ + .length = 0x1FE00000UL, /* 510MB */ .type = E820_TYPE_RAM }, - { /* lowmem to PCI hole */ - .baseaddr = 0x20000000UL, - .length = 0xa0000000UL, + { /* between lowmem and PCI hole */ + .baseaddr = 0x20000000UL, /* 512MB */ + .length = 0xA0000000UL, /* 2560MB */ .type = E820_TYPE_RESERVED }, - { /* PCI hole to 4G */ - .baseaddr = 0xe0000000UL, - .length = 0x20000000UL, + { /* between PCI hole and 4GB */ + .baseaddr = 0xe0000000UL, /* 3.5GB */ + .length = 0x20000000UL, /* 512MB */ .type = E820_TYPE_RESERVED }, }; diff --git a/hypervisor/arch/x86/configs/dnv-cb2/ve820.c b/hypervisor/arch/x86/configs/dnv-cb2/ve820.c index 6aa999b26..73d589e0e 100644 --- a/hypervisor/arch/x86/configs/dnv-cb2/ve820.c +++ b/hypervisor/arch/x86/configs/dnv-cb2/ve820.c @@ -7,33 +7,33 @@ #include const struct e820_entry ve820_entry[E820_MAX_ENTRIES] = { - { /* 0 to mptable */ + { /* usable RAM under 1MB */ .baseaddr = 0x0UL, - .length = 0xEFFFFUL, + .length = 0xF0000UL, /* 960KB */ .type = E820_TYPE_RAM }, - { /* mptable 65536U */ - .baseaddr = 0xF0000UL, - .length = 0x10000UL, + { /* mptable */ + .baseaddr = 0xF0000UL, /* 960KB */ + .length = 0x10000UL, /* 16KB */ .type = E820_TYPE_RESERVED }, - { /* mptable to lowmem */ - .baseaddr = 0x100000UL, - .length = 0x7FF00000UL, + { /* lowmem */ + .baseaddr = 0x200000UL, /* 2MB */ + .length = 0x7FE00000UL, /* 2046MB */ .type = E820_TYPE_RAM }, - { /* lowmem to PCI hole */ - .baseaddr = 0x80000000UL, - .length = 0x40000000UL, + { /* between lowmem and PCI hole */ + .baseaddr = 0x80000000UL, /* 2GB */ + .length = 0x40000000UL, /* 1GB */ .type = E820_TYPE_RESERVED }, - { /* PCI hole to 4G */ - .baseaddr = 0xe0000000UL, - .length = 0x20000000UL, + { /* between PCI hole and 4GB */ + .baseaddr = 0xe0000000UL, /* 3.5GB */ + .length = 0x20000000UL, /* 512MB */ .type = E820_TYPE_RESERVED }, }; diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index f1d99a183..9fafdaa28 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -141,6 +141,39 @@ static void create_prelaunched_vm_e820(struct acrn_vm *vm) vm->e820_entry_num = E820_MAX_ENTRIES; vm->e820_entries = (struct e820_entry *)ve820_entry; } + +/** + * @pre vm != NULL && vm_config != NULL + */ +static void prepare_prelaunched_vm_memmap(struct acrn_vm *vm, const struct acrn_vm_config *vm_config) +{ + uint64_t base_hpa = vm_config->memory.start_hpa; + uint32_t i; + + for (i = 0U; i < vm->e820_entry_num; i++) { + struct e820_entry *entry = &(vm->e820_entries[i]); + + if (entry->length == 0UL) { + break; + } + + /* Do EPT mapping for GPAs that are backed by physical memory */ + if (entry->type == E820_TYPE_RAM) { + ept_mr_add(vm, (uint64_t *)vm->arch_vm.nworld_eptp, base_hpa, entry->baseaddr, + entry->length, EPT_RWX | EPT_WB); + + base_hpa += entry->length; + } + + /* GPAs under 1MB are always backed by physical memory */ + if ((entry->type != E820_TYPE_RAM) && (entry->baseaddr < (uint64_t)MEM_1M)) { + ept_mr_add(vm, (uint64_t *)vm->arch_vm.nworld_eptp, base_hpa, entry->baseaddr, + entry->length, EPT_RWX | EPT_UNCACHED); + + base_hpa += entry->length; + } + } +} #endif /** @@ -324,9 +357,7 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_ &vm_config->GUID[0], sizeof(vm_config->GUID)); #ifdef CONFIG_PARTITION_MODE create_prelaunched_vm_e820(vm); - ept_mr_add(vm, (uint64_t *)vm->arch_vm.nworld_eptp, - vm_config->memory.start_hpa, 0UL, vm_config->memory.size, - EPT_RWX|EPT_WB); + prepare_prelaunched_vm_memmap(vm, vm_config); (void)init_vm_boot_info(vm); #endif }