mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-17 15:51:34 +00:00
HV: Using INIT to kick vCPUs off when RTVM poweroff by itself
When RTVM is trying to poweroff by itself, we use INIT to kick vCPUs off the non-root mode. For RTVM, only if vm state equal VM_POWERING_OFF, we take action to pause the vCPUs with INIT signal. Otherwise, we will reject the pause request. Tracked-On: #2865 Signed-off-by: Kaige Fu <kaige.fu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
2771b46b1d
commit
382acfaf28
@ -598,7 +598,13 @@ void pause_vcpu(struct acrn_vcpu *vcpu, enum vcpu_state new_state)
|
|||||||
|
|
||||||
if (atomic_load32(&vcpu->running) == 1U) {
|
if (atomic_load32(&vcpu->running) == 1U) {
|
||||||
remove_from_cpu_runqueue(&vcpu->sched_obj, vcpu->pcpu_id);
|
remove_from_cpu_runqueue(&vcpu->sched_obj, vcpu->pcpu_id);
|
||||||
make_reschedule_request(vcpu->pcpu_id, DEL_MODE_IPI);
|
|
||||||
|
if (is_lapic_pt(vcpu->vm)) {
|
||||||
|
make_reschedule_request(vcpu->pcpu_id, DEL_MODE_INIT);
|
||||||
|
} else {
|
||||||
|
make_reschedule_request(vcpu->pcpu_id, DEL_MODE_IPI);
|
||||||
|
}
|
||||||
|
|
||||||
release_schedule_lock(vcpu->pcpu_id);
|
release_schedule_lock(vcpu->pcpu_id);
|
||||||
|
|
||||||
if (vcpu->pcpu_id != pcpu_id) {
|
if (vcpu->pcpu_id != pcpu_id) {
|
||||||
|
@ -547,10 +547,21 @@ void pause_vm(struct acrn_vm *vm)
|
|||||||
struct acrn_vcpu *vcpu = NULL;
|
struct acrn_vcpu *vcpu = NULL;
|
||||||
|
|
||||||
if (vm->state != VM_PAUSED) {
|
if (vm->state != VM_PAUSED) {
|
||||||
vm->state = VM_PAUSED;
|
if (is_rt_vm(vm)) {
|
||||||
|
/* Only when RTVM is powering off by itself, we can pause vcpu */
|
||||||
|
if (vm->state == VM_POWERING_OFF) {
|
||||||
|
foreach_vcpu(i, vm, vcpu) {
|
||||||
|
pause_vcpu(vcpu, VCPU_ZOMBIE);
|
||||||
|
}
|
||||||
|
|
||||||
foreach_vcpu(i, vm, vcpu) {
|
vm->state = VM_PAUSED;
|
||||||
pause_vcpu(vcpu, VCPU_ZOMBIE);
|
}
|
||||||
|
} else {
|
||||||
|
foreach_vcpu(i, vm, vcpu) {
|
||||||
|
pause_vcpu(vcpu, VCPU_ZOMBIE);
|
||||||
|
}
|
||||||
|
|
||||||
|
vm->state = VM_PAUSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ static int32_t unhandled_vmexit_handler(struct acrn_vcpu *vcpu);
|
|||||||
static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu);
|
static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||||
static int32_t wbinvd_vmexit_handler(struct acrn_vcpu *vcpu);
|
static int32_t wbinvd_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||||
static int32_t undefined_vmexit_handler(struct acrn_vcpu *vcpu);
|
static int32_t undefined_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||||
|
static int32_t init_signal_vmexit_handler(__unused struct acrn_vcpu *vcpu);
|
||||||
|
|
||||||
/* VM Dispatch table for Exit condition handling */
|
/* VM Dispatch table for Exit condition handling */
|
||||||
static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = {
|
static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = {
|
||||||
@ -38,7 +39,7 @@ static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = {
|
|||||||
[VMX_EXIT_REASON_TRIPLE_FAULT] = {
|
[VMX_EXIT_REASON_TRIPLE_FAULT] = {
|
||||||
.handler = unhandled_vmexit_handler},
|
.handler = unhandled_vmexit_handler},
|
||||||
[VMX_EXIT_REASON_INIT_SIGNAL] = {
|
[VMX_EXIT_REASON_INIT_SIGNAL] = {
|
||||||
.handler = unhandled_vmexit_handler},
|
.handler = init_signal_vmexit_handler},
|
||||||
[VMX_EXIT_REASON_STARTUP_IPI] = {
|
[VMX_EXIT_REASON_STARTUP_IPI] = {
|
||||||
.handler = unhandled_vmexit_handler},
|
.handler = unhandled_vmexit_handler},
|
||||||
[VMX_EXIT_REASON_IO_SMI] = {
|
[VMX_EXIT_REASON_IO_SMI] = {
|
||||||
@ -343,3 +344,21 @@ static int32_t undefined_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
vcpu_inject_ud(vcpu);
|
vcpu_inject_ud(vcpu);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This handler is only triggered by INIT signal when poweroff from inside of RTVM
|
||||||
|
*/
|
||||||
|
static int32_t init_signal_vmexit_handler(__unused struct acrn_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Intel SDM Volume 3, 25.2:
|
||||||
|
* INIT signals. INIT signals cause VM exits. A logical processer performs none
|
||||||
|
* of the operations normally associated with these events. Such exits do not modify
|
||||||
|
* register state or clear pending events as they would outside of VMX operation (If
|
||||||
|
* a logical processor is the wait-for-SIPI state, INIT signals are blocked. They do
|
||||||
|
* not cause VM exits in this case).
|
||||||
|
*
|
||||||
|
* So, it is safe to ignore the signal and reture here.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user