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 <yadong.qi@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Qi Yadong 2018-05-25 09:30:37 +08:00 committed by lijinxia
parent ff96453993
commit b5b769f45a
9 changed files with 37 additions and 28 deletions

View File

@ -106,9 +106,8 @@ void destroy_ept(struct vm *vm)
* - trusty is enabled. But not initialized yet. * - trusty is enabled. But not initialized yet.
* Check vm->arch_vm.sworld_eptp. * Check vm->arch_vm.sworld_eptp.
*/ */
if (vm->sworld_control.sworld_enabled && if (vm->sworld_control.flag.active) {
(vm->arch_vm.sworld_eptp != NULL)) { free_ept_mem(HPA2HVA(vm->arch_vm.sworld_eptp));
free_ept_mem(vm->arch_vm.sworld_eptp);
vm->arch_vm.sworld_eptp = NULL; vm->arch_vm.sworld_eptp = NULL;
} }
} }

View File

@ -804,7 +804,7 @@ uint64_t create_guest_initial_paging(struct vm *vm)
* FIXME: this is a tempory solution for trusty enabling, * FIXME: this is a tempory solution for trusty enabling,
* the final solution is that vSBL will setup guest page tables * 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 */ /* clear page entry for trusty */
(void)memset(pml4_addr + 6U * PAGE_SIZE_4K, 0U, PAGE_SIZE_4K); (void)memset(pml4_addr + 6U * PAGE_SIZE_4K, 0U, PAGE_SIZE_4K);

View File

@ -156,8 +156,8 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm)
#endif #endif
} else { } else {
/* populate UOS vm fields according to vm_desc */ /* populate UOS vm fields according to vm_desc */
vm->sworld_control.sworld_enabled = vm->sworld_control.flag.supported =
vm_desc->sworld_enabled; vm_desc->sworld_supported;
(void)memcpy_s(&vm->GUID[0], sizeof(vm->GUID), (void)memcpy_s(&vm->GUID[0], sizeof(vm->GUID),
&vm_desc->GUID[0], &vm_desc->GUID[0],
sizeof(vm_desc->GUID)); sizeof(vm_desc->GUID));
@ -266,7 +266,7 @@ int shutdown_vm(struct vm *vm)
vioapic_cleanup(vm->arch_vm.virt_ioapic); vioapic_cleanup(vm->arch_vm.virt_ioapic);
/* Destroy secure world */ /* Destroy secure world */
if (vm->sworld_control.sworld_enabled) { if (vm->sworld_control.flag.active) {
destroy_secure_world(vm); destroy_secure_world(vm);
} }
/* Free EPT allocated resources assigned to VM */ /* Free EPT allocated resources assigned to VM */

View File

@ -175,8 +175,7 @@ void invept(struct vcpu *vcpu)
desc.eptp = HVA2HPA(vcpu->vm->arch_vm.nworld_eptp) | desc.eptp = HVA2HPA(vcpu->vm->arch_vm.nworld_eptp) |
(3UL << 3U) | 6UL; (3UL << 3U) | 6UL;
local_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); local_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc);
if (vcpu->vm->sworld_control.sworld_enabled && if (vcpu->vm->sworld_control.flag.active) {
vcpu->vm->arch_vm.sworld_eptp != NULL) {
desc.eptp = HVA2HPA(vcpu->vm->arch_vm.sworld_eptp) desc.eptp = HVA2HPA(vcpu->vm->arch_vm.sworld_eptp)
| (3UL << 3U) | 6UL; | (3UL << 3U) | 6UL;
local_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); local_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc);

View File

@ -92,9 +92,9 @@ static void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
return; return;
} }
if (!vm->sworld_control.sworld_enabled if (!vm->sworld_control.flag.supported
|| vm->arch_vm.sworld_eptp != NULL) { || 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; return;
} }
@ -164,8 +164,9 @@ static void create_secure_world_ept(struct vm *vm, uint64_t gpa_orig,
gpa, size); gpa, size);
/* Backup secure world info, will be used when /* Backup secure world info, will be used when
* destroy secure world */ * destroy secure world and suspend UOS */
vm->sworld_control.sworld_memory.base_gpa = gpa; 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.base_hpa = hpa;
vm->sworld_control.sworld_memory.length = size; 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_params.pml4_inverted = vm0->arch_vm.m2p;
map_mem(&map_params, (void *)vm->sworld_control.sworld_memory.base_hpa, 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, vm->sworld_control.sworld_memory.length,
(IA32E_EPT_R_BIT | (IA32E_EPT_R_BIT |
IA32E_EPT_W_BIT | IA32E_EPT_W_BIT |

View File

@ -181,7 +181,7 @@ int32_t hcall_create_vm(struct vm *vm, uint64_t param)
} }
(void)memset(&vm_desc, 0U, sizeof(vm_desc)); (void)memset(&vm_desc, 0U, sizeof(vm_desc));
vm_desc.sworld_enabled = vm_desc.sworld_supported =
((cv.vm_flag & (SECURE_WORLD_ENABLED)) != 0U); ((cv.vm_flag & (SECURE_WORLD_ENABLED)) != 0U);
(void)memcpy_s(&vm_desc.GUID[0], 16U, &cv.GUID[0], 16U); (void)memcpy_s(&vm_desc.GUID[0], 16U, &cv.GUID[0], 16U);
ret = create_vm(&vm_desc, &target_vm); ret = create_vm(&vm_desc, &target_vm);

View File

@ -20,13 +20,13 @@ int32_t hcall_world_switch(struct vcpu *vcpu)
return -EINVAL; return -EINVAL;
} }
if (!vcpu->vm->sworld_control.sworld_enabled) { if (!vcpu->vm->sworld_control.flag.supported) {
pr_err("%s, Secure World is not enabled!\n", __func__); pr_err("Secure World is not supported!\n");
return -EPERM; return -EPERM;
} }
if (vcpu->vm->arch_vm.sworld_eptp == NULL) { if (!vcpu->vm->sworld_control.flag.active) {
pr_err("%s, Trusty is not initialized!\n", __func__); pr_err("Trusty is not initialized!\n");
return -EPERM; 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) int32_t hcall_initialize_trusty(struct vcpu *vcpu, uint64_t param)
{ {
if (!vcpu->vm->sworld_control.sworld_enabled) { if (!vcpu->vm->sworld_control.flag.supported) {
pr_err("%s, Secure World is not enabled!\n", __func__); pr_err("Secure World is not supported!\n");
return -EPERM; return -EPERM;
} }
if (vcpu->vm->arch_vm.sworld_eptp != NULL) { if (vcpu->vm->sworld_control.flag.active) {
pr_err("%s, Trusty already initialized!\n", __func__); pr_err("Trusty already initialized!\n");
return -EPERM; return -EPERM;
} }
@ -59,5 +59,7 @@ int32_t hcall_initialize_trusty(struct vcpu *vcpu, uint64_t param)
return -ENODEV; return -ENODEV;
} }
vcpu->vm->sworld_control.flag.active = 1UL;
return 0; return 0;
} }

View File

@ -167,8 +167,8 @@ struct vm_description {
uint16_t *vm_pcpu_ids; uint16_t *vm_pcpu_ids;
unsigned char GUID[16]; /* GUID of the vm will be created */ unsigned char GUID[16]; /* GUID of the vm will be created */
uint16_t vm_hw_num_cores; /* Number of virtual cores */ uint16_t vm_hw_num_cores; /* Number of virtual cores */
/* Whether secure world is enabled for current VM. */ /* Whether secure world is supported for current VM. */
bool sworld_enabled; bool sworld_supported;
#ifdef CONFIG_PARTITION_MODE #ifdef CONFIG_PARTITION_MODE
uint8_t vm_id; uint8_t vm_id;
struct mptable_info *mptable; struct mptable_info *mptable;

View File

@ -92,7 +92,9 @@ struct trusty_key_info {
struct secure_world_memory { struct secure_world_memory {
/* The secure world base address of GPA in SOS */ /* 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 */ /* The secure world base address of HPA */
uint64_t base_hpa; uint64_t base_hpa;
/* Secure world runtime memory size */ /* Secure world runtime memory size */
@ -100,8 +102,14 @@ struct secure_world_memory {
}; };
struct secure_world_control { struct secure_world_control {
/* Whether secure world is enabled for current VM */ /* Flag indicates Secure World's state */
bool sworld_enabled; 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 */ /* Secure world memory structure */
struct secure_world_memory sworld_memory; struct secure_world_memory sworld_memory;
}; };