From b5b769f45a08c8e926171e6af8d0f6c53d36d697 Mon Sep 17 00:00:00 2001 From: Qi Yadong Date: Fri, 25 May 2018 09:30:37 +0800 Subject: [PATCH] HV: trusty: refine secure_world_control Define Bitmap flag to indicate secure world's state: supported: 0(not supported), 1(supported) active: 0(inactive), 1(active) Refine secure_world_memory: base_gpa_in_sos: base_gpa from SOS's view base_gpa_in_uos: base_gpa from UOS's view, this is the original base_gpa allocated by bootloader. Recording above GPA is for usage of trusty EPT destroy and re-create. There is an assumption: the secure world's memory address is contiguous in both SOS and physical side. Signed-off-by: Qi Yadong Acked-by: Eddie Dong --- hypervisor/arch/x86/ept.c | 5 ++--- hypervisor/arch/x86/guest/guest.c | 2 +- hypervisor/arch/x86/guest/vm.c | 6 +++--- hypervisor/arch/x86/mmu.c | 3 +-- hypervisor/arch/x86/trusty.c | 11 ++++++----- hypervisor/common/hypercall.c | 2 +- hypervisor/common/trusty_hypercall.c | 18 ++++++++++-------- hypervisor/include/arch/x86/guest/vm.h | 4 ++-- hypervisor/include/arch/x86/trusty.h | 14 +++++++++++--- 9 files changed, 37 insertions(+), 28 deletions(-) diff --git a/hypervisor/arch/x86/ept.c b/hypervisor/arch/x86/ept.c index 05ff193d0..d841f35f4 100644 --- a/hypervisor/arch/x86/ept.c +++ b/hypervisor/arch/x86/ept.c @@ -106,9 +106,8 @@ void destroy_ept(struct vm *vm) * - trusty is enabled. But not initialized yet. * Check vm->arch_vm.sworld_eptp. */ - if (vm->sworld_control.sworld_enabled && - (vm->arch_vm.sworld_eptp != NULL)) { - free_ept_mem(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; } } diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index d7a590908..536cf1ef9 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -804,7 +804,7 @@ uint64_t create_guest_initial_paging(struct vm *vm) * FIXME: this is a tempory solution for trusty enabling, * the final solution is that vSBL will setup guest page tables */ - if (vm->sworld_control.sworld_enabled && !is_vm0(vm)) { + if (vm->sworld_control.flag.supported && !is_vm0(vm)) { /* clear page entry for trusty */ (void)memset(pml4_addr + 6U * PAGE_SIZE_4K, 0U, PAGE_SIZE_4K); diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 6c4988bbd..0210d9b1b 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -156,8 +156,8 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm) #endif } else { /* populate UOS vm fields according to vm_desc */ - vm->sworld_control.sworld_enabled = - vm_desc->sworld_enabled; + vm->sworld_control.flag.supported = + vm_desc->sworld_supported; (void)memcpy_s(&vm->GUID[0], sizeof(vm->GUID), &vm_desc->GUID[0], sizeof(vm_desc->GUID)); @@ -266,7 +266,7 @@ int shutdown_vm(struct vm *vm) vioapic_cleanup(vm->arch_vm.virt_ioapic); /* Destroy secure world */ - if (vm->sworld_control.sworld_enabled) { + if (vm->sworld_control.flag.active) { destroy_secure_world(vm); } /* Free EPT allocated resources assigned to VM */ diff --git a/hypervisor/arch/x86/mmu.c b/hypervisor/arch/x86/mmu.c index 071eb9db3..957439557 100644 --- a/hypervisor/arch/x86/mmu.c +++ b/hypervisor/arch/x86/mmu.c @@ -175,8 +175,7 @@ void invept(struct vcpu *vcpu) desc.eptp = HVA2HPA(vcpu->vm->arch_vm.nworld_eptp) | (3UL << 3U) | 6UL; local_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); - if (vcpu->vm->sworld_control.sworld_enabled && - vcpu->vm->arch_vm.sworld_eptp != NULL) { + if (vcpu->vm->sworld_control.flag.active) { desc.eptp = HVA2HPA(vcpu->vm->arch_vm.sworld_eptp) | (3UL << 3U) | 6UL; local_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); diff --git a/hypervisor/arch/x86/trusty.c b/hypervisor/arch/x86/trusty.c index cd6829e55..dcb89d4b2 100644 --- a/hypervisor/arch/x86/trusty.c +++ b/hypervisor/arch/x86/trusty.c @@ -92,9 +92,9 @@ static void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig, return; } - if (!vm->sworld_control.sworld_enabled + if (!vm->sworld_control.flag.supported || vm->arch_vm.sworld_eptp != NULL) { - pr_err("Sworld is not enabled or Sworld eptp is not NULL"); + pr_err("Sworld is not supported or Sworld eptp is not NULL"); return; } @@ -164,8 +164,9 @@ static void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig, gpa, size); /* Backup secure world info, will be used when - * destroy secure world */ - vm->sworld_control.sworld_memory.base_gpa = gpa; + * destroy secure world and suspend UOS */ + vm->sworld_control.sworld_memory.base_gpa_in_sos = gpa; + vm->sworld_control.sworld_memory.base_gpa_in_uos = gpa_orig; vm->sworld_control.sworld_memory.base_hpa = hpa; vm->sworld_control.sworld_memory.length = size; @@ -194,7 +195,7 @@ void destroy_secure_world(struct vm *vm) 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, + (void *)vm->sworld_control.sworld_memory.base_gpa_in_sos, vm->sworld_control.sworld_memory.length, (IA32E_EPT_R_BIT | IA32E_EPT_W_BIT | diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 5dd85a3aa..f8efb35cc 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -181,7 +181,7 @@ int32_t hcall_create_vm(struct vm *vm, uint64_t param) } (void)memset(&vm_desc, 0U, sizeof(vm_desc)); - vm_desc.sworld_enabled = + 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); diff --git a/hypervisor/common/trusty_hypercall.c b/hypervisor/common/trusty_hypercall.c index f6cbdcebd..49c866acf 100644 --- a/hypervisor/common/trusty_hypercall.c +++ b/hypervisor/common/trusty_hypercall.c @@ -20,13 +20,13 @@ int32_t hcall_world_switch(struct vcpu *vcpu) return -EINVAL; } - if (!vcpu->vm->sworld_control.sworld_enabled) { - pr_err("%s, Secure World is not enabled!\n", __func__); + if (!vcpu->vm->sworld_control.flag.supported) { + pr_err("Secure World is not supported!\n"); return -EPERM; } - if (vcpu->vm->arch_vm.sworld_eptp == NULL) { - pr_err("%s, Trusty is not initialized!\n", __func__); + if (!vcpu->vm->sworld_control.flag.active) { + pr_err("Trusty is not initialized!\n"); return -EPERM; } @@ -39,13 +39,13 @@ int32_t hcall_world_switch(struct vcpu *vcpu) */ int32_t hcall_initialize_trusty(struct vcpu *vcpu, uint64_t param) { - if (!vcpu->vm->sworld_control.sworld_enabled) { - pr_err("%s, Secure World is not enabled!\n", __func__); + if (!vcpu->vm->sworld_control.flag.supported) { + pr_err("Secure World is not supported!\n"); return -EPERM; } - if (vcpu->vm->arch_vm.sworld_eptp != NULL) { - pr_err("%s, Trusty already initialized!\n", __func__); + if (vcpu->vm->sworld_control.flag.active) { + pr_err("Trusty already initialized!\n"); return -EPERM; } @@ -59,5 +59,7 @@ int32_t hcall_initialize_trusty(struct vcpu *vcpu, uint64_t param) return -ENODEV; } + vcpu->vm->sworld_control.flag.active = 1UL; + return 0; } diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index af46910a3..df7c83d11 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -167,8 +167,8 @@ struct vm_description { uint16_t *vm_pcpu_ids; unsigned char GUID[16]; /* GUID of the vm will be created */ uint16_t vm_hw_num_cores; /* Number of virtual cores */ - /* Whether secure world is enabled for current VM. */ - bool sworld_enabled; + /* Whether secure world is supported for current VM. */ + bool sworld_supported; #ifdef CONFIG_PARTITION_MODE uint8_t vm_id; struct mptable_info *mptable; diff --git a/hypervisor/include/arch/x86/trusty.h b/hypervisor/include/arch/x86/trusty.h index b014b1b8a..ce28c3bcd 100644 --- a/hypervisor/include/arch/x86/trusty.h +++ b/hypervisor/include/arch/x86/trusty.h @@ -92,7 +92,9 @@ struct trusty_key_info { struct secure_world_memory { /* The secure world base address of GPA in SOS */ - uint64_t base_gpa; + uint64_t base_gpa_in_sos; + /* The original secure world base address allocated by bootloader */ + uint64_t base_gpa_in_uos; /* The secure world base address of HPA */ uint64_t base_hpa; /* Secure world runtime memory size */ @@ -100,8 +102,14 @@ struct secure_world_memory { }; struct secure_world_control { - /* Whether secure world is enabled for current VM */ - bool sworld_enabled; + /* Flag indicates Secure World's state */ + struct { + /* secure world supporting: 0(unsupported), 1(supported) */ + uint64_t supported : 1; + /* secure world running status: 0(inactive), 1(active) */ + uint64_t active : 1; + uint64_t reserved : 62; + } flag; /* Secure world memory structure */ struct secure_world_memory sworld_memory; };