diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index d33261bef..7aeeb688b 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -590,6 +590,7 @@ static void vlapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, bool if ((lapic->svr.v & APIC_SVR_ENABLE) == 0U) { dev_dbg(ACRN_DBG_LAPIC, "vlapic is software disabled, ignoring interrupt %u", vector); } else { + signal_event(&vlapic->vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]); vlapic->ops->accept_intr(vlapic, vector, level); } } diff --git a/hypervisor/arch/x86/guest/vmcs.c b/hypervisor/arch/x86/guest/vmcs.c index ea58e80da..75a2893cd 100644 --- a/hypervisor/arch/x86/guest/vmcs.c +++ b/hypervisor/arch/x86/guest/vmcs.c @@ -272,7 +272,7 @@ static void init_exec_ctrl(struct acrn_vcpu *vcpu) value32 = check_vmx_ctrl(MSR_IA32_VMX_PROCBASED_CTLS, VMX_PROCBASED_CTLS_TSC_OFF | VMX_PROCBASED_CTLS_TPR_SHADOW | VMX_PROCBASED_CTLS_IO_BITMAP | VMX_PROCBASED_CTLS_MSR_BITMAP | - VMX_PROCBASED_CTLS_SECONDARY); + VMX_PROCBASED_CTLS_HLT | VMX_PROCBASED_CTLS_SECONDARY); /*Disable VM_EXIT for CR3 access*/ value32 &= ~(VMX_PROCBASED_CTLS_CR3_LOAD | VMX_PROCBASED_CTLS_CR3_STORE); diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c index f8b4e3aa9..20bc51aa4 100644 --- a/hypervisor/arch/x86/guest/vmexit.c +++ b/hypervisor/arch/x86/guest/vmexit.c @@ -31,6 +31,7 @@ static int32_t xsetbv_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 pause_vmexit_handler(__unused struct acrn_vcpu *vcpu); +static int32_t hlt_vmexit_handler(struct acrn_vcpu *vcpu); /* VM Dispatch table for Exit condition handling */ static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = { @@ -59,7 +60,7 @@ static const struct vm_exit_dispatch dispatch_table[NR_VMX_EXIT_REASONS] = { [VMX_EXIT_REASON_GETSEC] = { .handler = unhandled_vmexit_handler}, [VMX_EXIT_REASON_HLT] = { - .handler = unhandled_vmexit_handler}, + .handler = hlt_vmexit_handler}, [VMX_EXIT_REASON_INVD] = { .handler = unhandled_vmexit_handler}, [VMX_EXIT_REASON_INVLPG] = { @@ -284,6 +285,14 @@ static int32_t pause_vmexit_handler(__unused struct acrn_vcpu *vcpu) return 0; } +static int32_t hlt_vmexit_handler(struct acrn_vcpu *vcpu) +{ + if ((vcpu->arch.pending_req == 0UL) && (!vlapic_has_pending_intr(vcpu))) { + wait_event(&vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]); + } + return 0; +} + int32_t cpuid_vmexit_handler(struct acrn_vcpu *vcpu) { uint64_t rax, rbx, rcx, rdx; diff --git a/hypervisor/common/hv_main.c b/hypervisor/common/hv_main.c index e94914975..41ecc9c48 100644 --- a/hypervisor/common/hv_main.c +++ b/hypervisor/common/hv_main.c @@ -40,6 +40,7 @@ void vcpu_thread(struct thread_object *obj) continue; } + reset_event(&vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]); profiling_vmenter_handler(vcpu); TRACE_2L(TRACE_VM_ENTER, 0UL, 0UL);