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.
* 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;
}
}

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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