mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 04:02:05 +00:00
HV: trusty: new hypercall to save/restore context of secure world
New field in VM's structure: sworld_snapshot: save cpu_context of secure world. New hypercall: HC_SAVE_RESTORE_SWORLD_CTX In UOS S3 suspend path: trusty kernel driver will call this hypercall to require Hypervisor save context of secure world. In UOS S3 resume path: virtual firmware will call this hypercall to require Hypervisor restore context of secure world. New bit in secure_world_control.flag: ctx_saved: indicate whether cpu_context of secure world is saved. Signed-off-by: Qi Yadong <yadong.qi@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
3225b16e5f
commit
2fc3bdec40
@ -29,7 +29,8 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
|
||||
}
|
||||
|
||||
if (!is_vm0(vm) && hypcall_id != HC_WORLD_SWITCH &&
|
||||
hypcall_id != HC_INITIALIZE_TRUSTY) {
|
||||
hypcall_id != HC_INITIALIZE_TRUSTY &&
|
||||
hypcall_id != HC_SAVE_RESTORE_SWORLD_CTX) {
|
||||
pr_err("hypercall %d is only allowed from VM0!\n", hypcall_id);
|
||||
goto out;
|
||||
}
|
||||
@ -170,6 +171,10 @@ int vmcall_vmexit_handler(struct vcpu *vcpu)
|
||||
ret = hcall_get_cpu_pm_state(vm, param1, param2);
|
||||
break;
|
||||
|
||||
case HC_SAVE_RESTORE_SWORLD_CTX:
|
||||
ret = hcall_save_restore_sworld_ctx(vcpu);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("op %d: Invalid hypercall\n", hypcall_id);
|
||||
ret = -EPERM;
|
||||
|
@ -494,6 +494,30 @@ void trusty_set_dseed(void *dseed, uint8_t dseed_num)
|
||||
dseed, sizeof(struct seed_info) * dseed_num);
|
||||
}
|
||||
|
||||
void save_sworld_context(struct vcpu *vcpu)
|
||||
{
|
||||
memcpy_s(&vcpu->vm->sworld_snapshot,
|
||||
sizeof(struct cpu_context),
|
||||
&vcpu->arch_vcpu.contexts[SECURE_WORLD],
|
||||
sizeof(struct cpu_context));
|
||||
}
|
||||
|
||||
void restore_sworld_context(struct vcpu *vcpu)
|
||||
{
|
||||
struct secure_world_control *sworld_ctl =
|
||||
&vcpu->vm->sworld_control;
|
||||
|
||||
create_secure_world_ept(vcpu->vm,
|
||||
sworld_ctl->sworld_memory.base_gpa_in_uos,
|
||||
sworld_ctl->sworld_memory.length,
|
||||
TRUSTY_EPT_REBASE_GPA);
|
||||
|
||||
memcpy_s(&vcpu->arch_vcpu.contexts[SECURE_WORLD],
|
||||
sizeof(struct cpu_context),
|
||||
&vcpu->vm->sworld_snapshot,
|
||||
sizeof(struct cpu_context));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/ // End of trusty_apis
|
||||
|
@ -71,3 +71,34 @@ int32_t hcall_initialize_trusty(struct vcpu *vcpu, uint64_t param)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t hcall_save_restore_sworld_ctx(struct vcpu *vcpu)
|
||||
{
|
||||
struct vm *vm = vcpu->vm;
|
||||
|
||||
if (!vm->sworld_control.flag.supported) {
|
||||
dev_dbg(ACRN_DBG_TRUSTY_HYCALL,
|
||||
"Secure World is not supported!\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Currently, Secure World is only running on vCPU0 */
|
||||
if (!is_vcpu_bsp(vcpu)) {
|
||||
dev_dbg(ACRN_DBG_TRUSTY_HYCALL,
|
||||
"This hypercall is only allowed from vcpu0!");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (vm->sworld_control.flag.active) {
|
||||
save_sworld_context(vcpu);
|
||||
vm->sworld_control.flag.ctx_saved = 1UL;
|
||||
} else {
|
||||
if (vm->sworld_control.flag.ctx_saved) {
|
||||
restore_sworld_context(vcpu);
|
||||
vm->sworld_control.flag.ctx_saved = 0UL;
|
||||
vm->sworld_control.flag.active = 1UL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -153,6 +153,13 @@ struct vm {
|
||||
unsigned char GUID[16];
|
||||
struct secure_world_control sworld_control;
|
||||
|
||||
/* Secure World's snapshot
|
||||
* Currently, Secure World is only running on vcpu[0],
|
||||
* so the snapshot only stores the vcpu0's run_context
|
||||
* of secure world.
|
||||
*/
|
||||
struct cpu_context sworld_snapshot;
|
||||
|
||||
uint32_t vcpuid_entry_nr, vcpuid_level, vcpuid_xlevel;
|
||||
struct vcpuid_entry vcpuid_entries[MAX_VM_VCPUID_ENTRIES];
|
||||
#ifdef CONFIG_PARTITION_MODE
|
||||
|
@ -104,11 +104,13 @@ struct secure_world_memory {
|
||||
struct secure_world_control {
|
||||
/* Flag indicates Secure World's state */
|
||||
struct {
|
||||
/* secure world supporting: 0(unsupported), 1(supported) */
|
||||
/* sworld supporting: 0(unsupported), 1(supported) */
|
||||
uint64_t supported : 1;
|
||||
/* secure world running status: 0(inactive), 1(active) */
|
||||
/* sworld running status: 0(inactive), 1(active) */
|
||||
uint64_t active : 1;
|
||||
uint64_t reserved : 62;
|
||||
/* sworld context saving status: 0(unsaved), 1(saved) */
|
||||
uint64_t ctx_saved : 1;
|
||||
uint64_t reserved : 61;
|
||||
} flag;
|
||||
/* Secure world memory structure */
|
||||
struct secure_world_memory sworld_memory;
|
||||
@ -126,7 +128,8 @@ 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 save_sworld_context(struct vcpu *vcpu);
|
||||
void restore_sworld_context(struct vcpu *vcpu);
|
||||
void trusty_set_dseed(void *dseed, uint8_t dseed_num);
|
||||
|
||||
#endif /* TRUSTY_H_ */
|
||||
|
@ -397,6 +397,15 @@ int32_t hcall_world_switch(struct vcpu *vcpu);
|
||||
*/
|
||||
int32_t hcall_initialize_trusty(struct vcpu *vcpu, uint64_t param);
|
||||
|
||||
/**
|
||||
* @brief Save/Restore Context of Secure World.
|
||||
*
|
||||
* @param vcpu Pointer to VCPU data structure
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int64_t hcall_save_restore_sworld_ctx(struct vcpu *vcpu);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/ // End of trusty_hypercall
|
||||
|
@ -75,6 +75,7 @@
|
||||
#define HC_ID_TRUSTY_BASE 0x70UL
|
||||
#define HC_INITIALIZE_TRUSTY BASE_HC_ID(HC_ID, HC_ID_TRUSTY_BASE + 0x00UL)
|
||||
#define HC_WORLD_SWITCH BASE_HC_ID(HC_ID, HC_ID_TRUSTY_BASE + 0x01UL)
|
||||
#define HC_SAVE_RESTORE_SWORLD_CTX BASE_HC_ID(HC_ID, HC_ID_TRUSTY_BASE + 0x02UL)
|
||||
|
||||
/* Power management */
|
||||
#define HC_ID_PM_BASE 0x80UL
|
||||
|
Loading…
Reference in New Issue
Block a user