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 <fei1.li@intel.com>
This commit is contained in:
Li, Fei1 2018-11-28 22:21:15 +08:00 committed by wenlingz
parent 9bf7dd5ddc
commit bd1c0838d1
6 changed files with 40 additions and 14 deletions

View File

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

View File

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

View File

@ -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();

View File

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

View File

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

View File

@ -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 */