diff --git a/hypervisor/arch/x86/ept.c b/hypervisor/arch/x86/ept.c index d841f35f4..a7bcb43e9 100644 --- a/hypervisor/arch/x86/ept.c +++ b/hypervisor/arch/x86/ept.c @@ -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) diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index e95702c01..a874f7399 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -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); diff --git a/hypervisor/arch/x86/trusty.c b/hypervisor/arch/x86/trusty.c index 9ed5c5f2e..e410f8215 100644 --- a/hypervisor/arch/x86/trusty.c +++ b/hypervisor/arch/x86/trusty.c @@ -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) diff --git a/hypervisor/include/arch/x86/mmu.h b/hypervisor/include/arch/x86/mmu.h index 45dd57c94..276990354 100644 --- a/hypervisor/include/arch/x86/mmu.h +++ b/hypervisor/include/arch/x86/mmu.h @@ -389,7 +389,7 @@ int ept_mr_modify(struct vm *vm, uint64_t *pml4_page, uint64_t prot_set, uint64_t prot_clr); int ept_mr_del(struct vm *vm, uint64_t *pml4_page, uint64_t gpa, uint64_t size); - +void free_ept_mem(void *pml4_addr); int ept_violation_vmexit_handler(struct vcpu *vcpu); int ept_misconfig_vmexit_handler(__unused struct vcpu *vcpu); diff --git a/hypervisor/include/arch/x86/trusty.h b/hypervisor/include/arch/x86/trusty.h index 0c3836783..22c673fea 100644 --- a/hypervisor/include/arch/x86/trusty.h +++ b/hypervisor/include/arch/x86/trusty.h @@ -16,6 +16,8 @@ #define TRUSTY_EPT_REBASE_GPA (511UL * 1024UL * 1024UL * 1024UL) #define TRUSTY_MEMORY_SIZE 0x01000000 +#define NON_TRUSTY_PDPT_ENTRIES 511U + /* Structure of seed info */ struct seed_info { uint8_t cse_svn; @@ -127,7 +129,7 @@ struct trusty_startup_param { void switch_world(struct vcpu *vcpu, int next_world); bool initialize_trusty(struct vcpu *vcpu, uint64_t param); -void destroy_secure_world(struct vm *vm); +void destroy_secure_world(struct vm *vm, bool need_clr_mem); void save_sworld_context(struct vcpu *vcpu); void restore_sworld_context(struct vcpu *vcpu); void trusty_set_dseed(void *dseed, uint8_t dseed_num);