From bd1c0838d1c1624155eb2ceb9f7f5e69f69e21a1 Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Wed, 28 Nov 2018 22:21:15 +0800 Subject: [PATCH] hv: trusty: reserve memory for trusty The previous would reserve memory for trusty in SOS kernel. Howerer, there would no available 16 MB continue memory any more after a long time. This result in allocating memory for trusty failed. This patch will reserve memory for trusty in ACRN hypervisor in which case the memory allocation for trusty will never fail. Tracked-On: #1942 Signed-off-by: Li, Fei1 --- hypervisor/arch/x86/Kconfig | 4 ++-- hypervisor/arch/x86/guest/vm.c | 13 +++++++++---- hypervisor/arch/x86/mmu.c | 11 ++++++++--- hypervisor/arch/x86/page.c | 15 +++++++++++++++ hypervisor/common/hypercall.c | 8 +++----- hypervisor/include/arch/x86/page.h | 3 +++ 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index 0e4819c1b..75cb54b7e 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -267,8 +267,8 @@ config HV_RAM_START config HV_RAM_SIZE hex "Size of the RAM region used by the hypervisor" - default 0x04800000 if PLATFORM_SBL - default 0x08000000 if PLATFORM_UEFI + default 0x07800000 if PLATFORM_SBL + default 0x0b000000 if PLATFORM_UEFI help A 64-bit integer indicating the size of RAM used by the hypervisor. It is ensured at link time that the footprint of the hypervisor diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 6c647462f..7fdea5ace 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -110,11 +110,16 @@ int create_vm(struct vm_description *vm_desc, struct acrn_vm **rtn_vm) init_iommu_vm0_domain(vm); } else { /* populate UOS vm fields according to vm_desc */ - vm->sworld_control.flag.supported = - vm_desc->sworld_supported; + vm->sworld_control.flag.supported = vm_desc->sworld_supported; + if (vm->sworld_control.flag.supported != 0UL) { + struct memory_ops *ept_mem_ops = &vm->arch_vm.ept_mem_ops; + ept_mr_add(vm, (uint64_t *)vm->arch_vm.nworld_eptp, + hva2hpa(ept_mem_ops->get_sworld_memory_base(ept_mem_ops->info)), + TRUSTY_EPT_REBASE_GPA, TRUSTY_RAM_SIZE, EPT_WB | EPT_RWX); + } + (void)memcpy_s(&vm->GUID[0], sizeof(vm->GUID), - &vm_desc->GUID[0], - sizeof(vm_desc->GUID)); + &vm_desc->GUID[0], sizeof(vm_desc->GUID)); #ifdef CONFIG_PARTITION_MODE ept_mr_add(vm, (uint64_t *)vm->arch_vm.nworld_eptp, vm_desc->start_hpa, 0UL, vm_desc->mem_size, diff --git a/hypervisor/arch/x86/mmu.c b/hypervisor/arch/x86/mmu.c index e5c539cc4..683245f34 100644 --- a/hypervisor/arch/x86/mmu.c +++ b/hypervisor/arch/x86/mmu.c @@ -275,15 +275,20 @@ void init_paging(void) mmu_modify_or_del((uint64_t *)ppt_mmu_pml4_addr, (1UL << 32U), high64_max_ram - (1UL << 32U), PAGE_CACHE_WB, PAGE_CACHE_MASK, &ppt_mem_ops, MR_MODIFY); - /* set the paging-structure entries' U/S flag - * to supervisor-mode for hypervisor owned memroy. + /* + * set the paging-structure entries' U/S flag to supervisor-mode for hypervisor owned memroy. + * (exclude the memory reserve for trusty) */ hv_hpa = get_hv_image_base(); mmu_modify_or_del((uint64_t *)ppt_mmu_pml4_addr, hv_hpa & PDE_MASK, - CONFIG_HV_RAM_SIZE + (((hv_hpa & (PDE_SIZE - 1UL)) != 0UL) ? PDE_SIZE : 0UL), + CONFIG_HV_RAM_SIZE + (((hv_hpa & (PDE_SIZE - 1UL)) != 0UL) ? PDE_SIZE : 0UL), PAGE_CACHE_WB, PAGE_CACHE_MASK | PAGE_USER, &ppt_mem_ops, MR_MODIFY); + mmu_modify_or_del((uint64_t *)ppt_mmu_pml4_addr, (uint64_t)get_reserve_sworld_memory_base(), + TRUSTY_RAM_SIZE * (CONFIG_MAX_VM_NUM - 1U), + PAGE_USER, 0UL, &ppt_mem_ops, MR_MODIFY); + /* Enable paging */ enable_paging(); diff --git a/hypervisor/arch/x86/page.c b/hypervisor/arch/x86/page.c index e6f523bcc..610751cec 100644 --- a/hypervisor/arch/x86/page.c +++ b/hypervisor/arch/x86/page.c @@ -70,6 +70,8 @@ static struct page uos_nworld_pd_pages[CONFIG_MAX_VM_NUM - 1U][PD_PAGE_NUM(EPT_A static struct page uos_nworld_pt_pages[CONFIG_MAX_VM_NUM - 1U][PT_PAGE_NUM(EPT_ADDRESS_SPACE(CONFIG_UOS_RAM_SIZE))]; static struct page uos_sworld_pgtable_pages[CONFIG_MAX_VM_NUM - 1U][TRUSTY_PGTABLE_PAGE_NUM(TRUSTY_RAM_SIZE)]; +/* pre-assumption: TRUSTY_RAM_SIZE is 2M aligned */ +static struct page uos_sworld_memory[CONFIG_MAX_VM_NUM - 1U][TRUSTY_RAM_SIZE >> PAGE_SHIFT] __aligned(MEM_2M); /* ept: extended page table*/ static union pgtable_pages_info ept_pages_info[CONFIG_MAX_VM_NUM] = { @@ -84,6 +86,11 @@ static union pgtable_pages_info ept_pages_info[CONFIG_MAX_VM_NUM] = { }, }; +void *get_reserve_sworld_memory_base(void) +{ + return uos_sworld_memory; +} + static inline uint64_t ept_get_default_access_right(void) { return EPT_RWX; @@ -135,6 +142,11 @@ static inline struct page *ept_get_pt_page(const union pgtable_pages_info *info, return page; } +static inline void *ept_get_sworld_memory_base(const union pgtable_pages_info *info) +{ + return info->ept.sworld_memory_base; +} + void init_ept_mem_ops(struct acrn_vm *vm) { uint16_t vm_id = vm->vm_id; @@ -145,6 +157,9 @@ void init_ept_mem_ops(struct acrn_vm *vm) ept_pages_info[vm_id].ept.nworld_pd_base = uos_nworld_pd_pages[vm_id - 1U]; ept_pages_info[vm_id].ept.nworld_pt_base = uos_nworld_pt_pages[vm_id - 1U]; ept_pages_info[vm_id].ept.sworld_pgtable_base = uos_sworld_pgtable_pages[vm_id - 1U]; + ept_pages_info[vm_id].ept.sworld_memory_base = uos_sworld_memory[vm_id - 1U]; + + vm->arch_vm.ept_mem_ops.get_sworld_memory_base = ept_get_sworld_memory_base; } vm->arch_vm.ept_mem_ops.info = &ept_pages_info[vm_id]; diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 057505473..2d7ccbfd0 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -119,8 +119,7 @@ int32_t hcall_create_vm(struct acrn_vm *vm, uint64_t param) } (void)memset(&vm_desc, 0U, sizeof(vm_desc)); - vm_desc.sworld_supported = - ((cv.vm_flag & (SECURE_WORLD_ENABLED)) != 0U); + vm_desc.sworld_supported = ((cv.vm_flag & (SECURE_WORLD_ENABLED)) != 0U); (void)memcpy_s(&vm_desc.GUID[0], 16U, &cv.GUID[0], 16U); ret = create_vm(&vm_desc, &target_vm); @@ -515,11 +514,10 @@ static int32_t set_vm_memory_region(struct acrn_vm *vm, } gpa_end = region->gpa + region->size; - if ((gpa_end > vm->arch_vm.ept_mem_ops.info->ept.top_address_space) && - (region->gpa < TRUSTY_EPT_REBASE_GPA)) { + if (gpa_end > vm->arch_vm.ept_mem_ops.info->ept.top_address_space) { pr_err("%s, invalid gpa: 0x%llx, size: 0x%llx, top_address_space: 0x%llx", __func__, region->gpa, region->size, vm->arch_vm.ept_mem_ops.info->ept.top_address_space); - return -EINVAL; + return 0; } dev_dbg(ACRN_DBG_HYCALL, diff --git a/hypervisor/include/arch/x86/page.h b/hypervisor/include/arch/x86/page.h index 87cf36045..046ab601d 100644 --- a/hypervisor/include/arch/x86/page.h +++ b/hypervisor/include/arch/x86/page.h @@ -46,6 +46,7 @@ union pgtable_pages_info { struct page *nworld_pd_base; struct page *nworld_pt_base; struct page *sworld_pgtable_base; + struct page *sworld_memory_base; } ept; }; @@ -57,9 +58,11 @@ struct memory_ops { struct page *(*get_pdpt_page)(const union pgtable_pages_info *info, uint64_t gpa); struct page *(*get_pd_page)(const union pgtable_pages_info *info, uint64_t gpa); struct page *(*get_pt_page)(const union pgtable_pages_info *info, uint64_t gpa); + void *(*get_sworld_memory_base)(const union pgtable_pages_info *info); }; extern const struct memory_ops ppt_mem_ops; void init_ept_mem_ops(struct acrn_vm *vm); +void *get_reserve_sworld_memory_base(void); #endif /* PAGE_H */