hv:add pre-condition for vm APIs

check the vm state in hypercall api,
add pre-condition for vm api.

Tracked-On: #4320
Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Jason Chen CJ 2020-04-13 14:40:08 +08:00 committed by wenlingz
parent fe929d0a10
commit 0584981c03
3 changed files with 64 additions and 72 deletions

View File

@ -70,6 +70,14 @@ bool is_created_vm(const struct acrn_vm *vm)
return (vm->state == VM_CREATED);
}
/**
* @pre vm != NULL
*/
bool is_paused_vm(const struct acrn_vm *vm)
{
return (vm->state == VM_PAUSED);
}
bool is_sos_vm(const struct acrn_vm *vm)
{
return (vm != NULL) && (get_vm_config(vm->vm_id)->load_order == SOS_VM);
@ -575,6 +583,7 @@ static int32_t offline_lapic_pt_enabled_pcpus(const struct acrn_vm *vm, uint64_t
/*
* @pre vm != NULL
* @pre vm->state == VM_PAUSED
*/
int32_t shutdown_vm(struct acrn_vm *vm)
{
@ -585,7 +594,6 @@ int32_t shutdown_vm(struct acrn_vm *vm)
int32_t ret = 0;
/* Only allow shutdown paused vm */
if (vm->state == VM_PAUSED) {
vm->state = VM_POWERED_OFF;
vm_config = get_vm_config(vm->vm_id);
@ -610,9 +618,6 @@ int32_t shutdown_vm(struct acrn_vm *vm)
foreach_vcpu(i, vm, vcpu) {
offline_vcpu(vcpu);
}
} else {
ret = -EINVAL;
}
if (is_ready_for_system_shutdown()) {
/* If no any guest running, shutdown system */
@ -624,7 +629,8 @@ int32_t shutdown_vm(struct acrn_vm *vm)
}
/**
* * @pre vm != NULL
* @pre vm != NULL
* @pre vm->state == VM_CREATED
*/
void start_vm(struct acrn_vm *vm)
{
@ -639,7 +645,8 @@ void start_vm(struct acrn_vm *vm)
}
/**
* * @pre vm != NULL
* @pre vm != NULL
* @pre vm->state == VM_PAUSED
*/
int32_t reset_vm(struct acrn_vm *vm)
{
@ -648,7 +655,6 @@ int32_t reset_vm(struct acrn_vm *vm)
struct acrn_vcpu *vcpu = NULL;
int32_t ret = 0;
if (vm->state == VM_PAUSED) {
mask = lapic_pt_enabled_pcpu_bitmap(vm);
if (mask != 0UL) {
ret = offline_lapic_pt_enabled_pcpus(vm, mask);
@ -664,7 +670,7 @@ int32_t reset_vm(struct acrn_vm *vm)
vm->arch_vm.vlapic_state = VM_VLAPIC_XAPIC;
if (is_sos_vm(vm)) {
(void )vm_sw_loader(vm);
(void)vm_sw_loader(vm);
}
reset_vm_ioreqs(vm);
@ -672,43 +678,27 @@ int32_t reset_vm(struct acrn_vm *vm)
destroy_secure_world(vm, false);
vm->sworld_control.flag.active = 0UL;
vm->state = VM_CREATED;
} else {
ret = -EINVAL;
}
return ret;
}
/**
* * @pre vm != NULL
* @pre vm != NULL
*/
void pause_vm(struct acrn_vm *vm)
{
uint16_t i;
struct acrn_vcpu *vcpu = NULL;
if (vm->state != VM_PAUSED) {
if (is_rt_vm(vm)) {
/**
* For RTVM, we can only pause its vCPUs when it stays at following states:
* - It is powering off by itself
* - It is created but doesn't start
*/
if ((vm->state == VM_READY_TO_POWEROFF) || (vm->state == VM_CREATED)) {
/* For RTVM, we can only pause its vCPUs when it is powering off by itself */
if (((!is_rt_vm(vm)) && (vm->state == VM_RUNNING)) ||
((is_rt_vm(vm)) && (vm->state == VM_READY_TO_POWEROFF)) ||
(vm->state == VM_CREATED)) {
foreach_vcpu(i, vm, vcpu) {
pause_vcpu(vcpu, VCPU_ZOMBIE);
}
vm->state = VM_PAUSED;
}
} else {
foreach_vcpu(i, vm, vcpu) {
pause_vcpu(vcpu, VCPU_ZOMBIE);
}
vm->state = VM_PAUSED;
}
}
}
/**
@ -724,6 +714,7 @@ void pause_vm(struct acrn_vm *vm)
* @wakeup_vec[in] The resume address of vm
*
* @pre vm != NULL
* @pre is_sos_vm(vm) && vm->state == VM_PAUSED
*/
void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec)
{
@ -759,7 +750,7 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config)
build_vacpi(vm);
}
(void )vm_sw_loader(vm);
(void)vm_sw_loader(vm);
/* start vm BSP automatically */
start_vm(vm);

View File

@ -203,7 +203,7 @@ int32_t hcall_destroy_vm(uint16_t vmid)
int32_t ret = -1;
struct acrn_vm *target_vm = get_vm_from_vmid(vmid);
if (!is_poweroff_vm(target_vm) && is_postlaunched_vm(target_vm)) {
if (is_paused_vm(target_vm) && is_postlaunched_vm(target_vm)) {
/* TODO: check target_vm guest_flags */
ret = shutdown_vm(target_vm);
}
@ -278,7 +278,7 @@ int32_t hcall_reset_vm(uint16_t vmid)
struct acrn_vm *target_vm = get_vm_from_vmid(vmid);
int32_t ret = -1;
if (!is_poweroff_vm(target_vm) && is_postlaunched_vm(target_vm)) {
if (is_paused_vm(target_vm) && is_postlaunched_vm(target_vm)) {
/* TODO: check target_vm guest_flags */
ret = reset_vm(target_vm);
}

View File

@ -244,6 +244,7 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config);
void launch_vms(uint16_t pcpu_id);
bool is_poweroff_vm(const struct acrn_vm *vm);
bool is_created_vm(const struct acrn_vm *vm);
bool is_paused_vm(const struct acrn_vm *vm);
bool is_sos_vm(const struct acrn_vm *vm);
bool is_postlaunched_vm(const struct acrn_vm *vm);
bool is_prelaunched_vm(const struct acrn_vm *vm);