mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-07 20:00:13 +00:00
hv:Refine destroy_secure_world API
-- add clear trusty memory flag In some cases such as UOS power off or UOS full reset, need to clear trusty memory,no need to clear memory such as UOS S3 or UOS system reset,then add a flag to distinguish it when destroy secure world. -- Restore trusty memory to guest normal world. -- Moved free trusty EPT inside destroy_secure_world In some cases such as UOS S3 or UOS system reset, only need to free trusty EPT, this patch move free trusty EPT inside destroy_secure_world. Because PD/PT are shared in both secure world's EPT and normal world's EPT,before freeing trusty EPT, it will memset all PDPTEs except trusty memory, then call 'free_ept_mem', it can only free trusty EPT, and does't affect shared normal world EPT. v2-->v3: -- Used new mmu api ept_mr_add when restore trusty memory to SOS and normal world -- Dropped this patch "Removed reverted page tables for trusty memory" because map_mem will be removed in future It will have a patch, need to update this api(ept_mr_add), it will not create inverted page tables for trusty memory. v1-->v2: -- free trusty ept still use free_ept_mem, not add a new api,but need to memset pdptes except trusty memory -- Removed reverted page tables for trusty memory. Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
@@ -45,7 +45,7 @@ static uint64_t find_next_table(uint32_t table_offset, void *table_base)
|
||||
/**
|
||||
* @pre pml4_addr != NULL
|
||||
*/
|
||||
static void free_ept_mem(void *pml4_addr)
|
||||
void free_ept_mem(void *pml4_addr)
|
||||
{
|
||||
void *pdpt_addr;
|
||||
void *pde_addr;
|
||||
@@ -98,18 +98,6 @@ void destroy_ept(struct vm *vm)
|
||||
free_ept_mem(vm->arch_vm.nworld_eptp);
|
||||
if (vm->arch_vm.m2p != NULL)
|
||||
free_ept_mem(vm->arch_vm.m2p);
|
||||
|
||||
/*
|
||||
* If secure world is initialized, destroy Secure world ept.
|
||||
* There are two cases secure world is not initialized:
|
||||
* - trusty is not enabled. Check sworld_enabled.
|
||||
* - trusty is enabled. But not initialized yet.
|
||||
* Check vm->arch_vm.sworld_eptp.
|
||||
*/
|
||||
if (vm->sworld_control.flag.active) {
|
||||
free_ept_mem(HPA2HVA(vm->arch_vm.sworld_eptp));
|
||||
vm->arch_vm.sworld_eptp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t local_gpa2hpa(struct vm *vm, uint64_t gpa, uint32_t *size)
|
||||
|
@@ -271,7 +271,7 @@ int shutdown_vm(struct vm *vm)
|
||||
|
||||
/* Destroy secure world */
|
||||
if (vm->sworld_control.flag.active) {
|
||||
destroy_secure_world(vm);
|
||||
destroy_secure_world(vm, true);
|
||||
}
|
||||
/* Free EPT allocated resources assigned to VM */
|
||||
destroy_ept(vm);
|
||||
|
@@ -131,8 +131,8 @@ static void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
|
||||
dest_pdpte_p++;
|
||||
}
|
||||
|
||||
/* Map gpa_rebased~gpa_rebased+size
|
||||
* to secure ept mapping
|
||||
/* Map gpa_rebased~gpa_rebased+size to secure ept mapping
|
||||
* TODO: not create inverted page tables for trusty memory
|
||||
*/
|
||||
map_params.page_table_type = PTT_EPT;
|
||||
map_params.pml4_inverted = vm->arch_vm.m2p;
|
||||
@@ -162,33 +162,49 @@ static void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_secure_world(struct vm *vm)
|
||||
void destroy_secure_world(struct vm *vm, bool need_clr_mem)
|
||||
{
|
||||
struct mem_map_params map_params;
|
||||
void *pdpt_addr;
|
||||
struct vm *vm0 = get_vm_from_vmid(0U);
|
||||
|
||||
if (vm0 == NULL) {
|
||||
pr_err("Parse vm0 context failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* clear trusty memory space */
|
||||
(void)memset(HPA2HVA(vm->sworld_control.sworld_memory.base_hpa),
|
||||
0, vm->sworld_control.sworld_memory.length);
|
||||
if (need_clr_mem) {
|
||||
/* clear trusty memory space */
|
||||
(void)memset(HPA2HVA(vm->sworld_control.sworld_memory.base_hpa),
|
||||
0U, vm->sworld_control.sworld_memory.length);
|
||||
}
|
||||
|
||||
/* restore memory to SOS ept mapping */
|
||||
map_params.page_table_type = PTT_EPT;
|
||||
map_params.pml4_base = vm0->arch_vm.nworld_eptp;
|
||||
map_params.pml4_inverted = vm0->arch_vm.m2p;
|
||||
|
||||
map_mem(&map_params, (void *)vm->sworld_control.sworld_memory.base_hpa,
|
||||
(void *)vm->sworld_control.sworld_memory.base_gpa_in_sos,
|
||||
if (ept_mr_add(vm0, vm->sworld_control.sworld_memory.base_hpa,
|
||||
vm->sworld_control.sworld_memory.base_gpa_in_sos,
|
||||
vm->sworld_control.sworld_memory.length,
|
||||
(IA32E_EPT_R_BIT |
|
||||
IA32E_EPT_W_BIT |
|
||||
IA32E_EPT_X_BIT |
|
||||
IA32E_EPT_WB));
|
||||
EPT_RWX | EPT_WB) != 0) {
|
||||
pr_warn("Restore trusty mem to SOS failed");
|
||||
}
|
||||
|
||||
/* Restore memory to guest normal world */
|
||||
if (ept_mr_add(vm, vm->sworld_control.sworld_memory.base_hpa,
|
||||
vm->sworld_control.sworld_memory.base_gpa_in_uos,
|
||||
vm->sworld_control.sworld_memory.length,
|
||||
EPT_RWX | EPT_WB) != 0) {
|
||||
pr_warn("Restore trusty mem to nworld failed");
|
||||
}
|
||||
|
||||
/* Free trusty ept page-structures */
|
||||
if (vm->arch_vm.sworld_eptp != NULL) {
|
||||
pdpt_addr =
|
||||
(void *)pml4e_page_vaddr(*(uint64_t *)vm->arch_vm.sworld_eptp);
|
||||
/* memset PDPTEs except trusty memory */
|
||||
(void)memset(pdpt_addr, 0UL,
|
||||
NON_TRUSTY_PDPT_ENTRIES * IA32E_COMM_ENTRY_SIZE);
|
||||
free_ept_mem(vm->arch_vm.sworld_eptp);
|
||||
vm->arch_vm.sworld_eptp = NULL;
|
||||
} else {
|
||||
pr_err("sworld eptp is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
static void save_world_ctx(struct vcpu *vcpu, struct ext_context *ext_ctx)
|
||||
|
Reference in New Issue
Block a user